.alone←declaration(expurgate)=0;
.if alone then start
.require "<altosource>ttydefs.pub" source!file
.end
.every heading (|CopyDisk|,|November 12, 1980|,{page})
.once center
~CopyDisk~
.skip 3
CopyDisk is a program for copying entire disk packs.  It will copy from one drive to another on the same machine, or between drives on separate machines via a network.

.sec |History|

The first Alto CopyDisk was called Quick and was written by Gene McDaniel in 1973.  During the summer of 1975 Graeme Williams wrote a new CopyDisk adding the ability to copy disks over the network.  During the summer of 1976 David Boggs redesigned the network protocol and added the ability to copy Trident disks.  In the spring of 1980 the network protocol was extended to speak to CopyDisk servers in Interim File Systems (and eventually Tape servers).  The CopyDisk network protocol is specified in <Pup>CopyDisk.press.

.sec |Concepts and Terminology|

In a disk copy operation, the information on a 'Source' disk is copied to a 'Destination' disk, destroying any previous information on the destination.  A copy operation usually consists of two steps:

.begin indent 5,5,5
[Copy] Step one copies bit-for-bit the information from the source disk to the destination disk.

[Check] Step two reads the destination disk and checks that it is indentical with the source disk.  This step can be omitted at the user's peril.
.end

Copying a disk from one machine (or 'host') to another over a network requires the active cooperation of programs on both machines.  In a typical scenario, a human user invokes a program called a 'CopyDisk User' and directs it to establish contact with a 'CopyDisk Server' on another machine.  Once contact has been established, the CopyDisk User initiates requests and supplies parameters for the actual copy operation which the User and Server carry out together.  The User and Server roles differ in that the CopyDisk User interacts with a human user (usually through some keyboard interpreter) and takes the initiative in User/Server interactions, whereas the CopyDisk Server plays a comparatively passive role.  The question of which machine is the CopyDisk User and which is the CopyDisk Server is independent of the direction in which data moves.

The Alto CopyDisk subsystem contains both a CopyDisk User and a CopyDisk Server, running as independent processes.  Therefore to copy a disk from one machine to another you should start up the CopyDisk subsystem on both machines and then type commands to one of them, which becomes the CopyDisk User.  Subsequent operations are controlled entirely from the User end, with no human intervention required at the Server machine.  This arrangement is similar to the way the Alto FTP subsystem works, and different from the way the older CopyDisk worked.

.sec |Calling CopyDisk|

CopyDisk can be run in two modes: interactive mode in which commands come from the keyboard, and non-interactive mode in which commands come from the command line (Com.cm).  The general form of the command line to invoke CopyDisk looks like:
.begin center

CopyDisk [ [/<option switches>] [from] <source> [to] <destination>]
.end

The square brackets denote portions of the command line that are optional and may be omitted.  If you just type "CopyDisk" the program goes into interactive mode, otherwise the remainder of the command line must be a complete description of the desired operation.

.ssec |Option Switches|

Each option switch has a default value which is used if the switch is not explicitly set.  To set a switch to 'false' proceed it with a 'minus' sign (thus CopyDisk/-C means 'no checking').  To set a switch to 'true' just mention the switch.

.begin indent 0,19 tabs 10,20
Switch\Default\Function

/4\false\[Model44] tells CopyDisk to copy an entire Diablo model 44, without asking for confirmation.

/C\true\[Check] tells CopyDisk whether to check the copy operation.  CopyDisk/-C, which omits the check step, is faster but more risky.

/W\true\[WriteProtect] prevents the CopyDisk network Server from writing on a local disk.  So unless you say CopyDisk/W or issue the WRITEPROTECT command, someone can make a copy of your disk over the network, but no one can (maliciously or accidentally) overwrite it.

/R\true\[Ram] tells CopyDisk to attempt to load the ram with some microcode which speeds things up considerably.  CopyDisk will still work, though more slowly if it can't load the ram.

/D\false\[Debug] enables extra printout that should be interesting only to CopyDisk maintainers.

/A\false\[AllocatorDebug] enables extra consistancy checks in the free storage allocator.
.end

.ssec |Source and Destination Syntax|

The general form of a source or destination disk name is:
.begin center

[Host-name]Disk-name
.end

for example "[Boggs]DP0".  Ordinarily 'host name' can be a string, e.g., "Boggs".  Most Altos have names which are registered in Name Lookup Servers.  So long as a name lookup server is available, CopyDisk is able to obtain the information necessary to translate a host name to an inter-network address (which is what the underlying network mechanism uses).  You may omit the host name for disks attached to the local machine.

If the host name of the Server machine is not known, you may specify an inter-network address in its place.  The general form of an inter-network address is:
.begin center

<network> # <host> # <socket>
.end

where each of the three fields is an octal number.  The <network> number designates the network to which the Server host is connected (which may be different from the one to which the User host is connected); this (along with the "#" that follows it) may be omitted if the Server and User are known to be connected to the same network.  The <host> number designates the Server host's address on <network>.  The <socket> number designates the actual Server process on that host; ordinarily it should be omitted, since the default is the regular CopyDisk server socket.  Hence to specify a CopyDisk server running in Alto host number 241 on the directly connected network, you should say "241#" (the trailing "#" is required).

The 'disk-name' is interpreted by the CopyDisk program on the host where the disk is.  This program knows how to copy two types of disks, which should be referred to by the following names:

.begin indent 5,19,5 tabs 20
DPn\Diablo disk unit 'n'.  Most Altos have one Diablo disk called 'DP0'.

TPn\Trident disk unit 'n'.  The unit number must be in the range 0-7.
.end

In addition, you may tell CopyDisk to copy an entire Alto file system by referring to it by the name 'BFS', (for Basic File System, which is the name of the software package that implements it).  If you use this name rather than 'DP0' or whatever, you won't have to answer questions such as whether the disk is a model 31 or a model 44.  Best of all, CopyDisk can detect that its a double-disk file system, and it will copy both disks automatically.

When you are copying through the network to another random Alto (as opposed to say, an IFS or a Tape server), you are presumably talking to another instance of this program, so you use the above syntax when referring to its disks.

When you are copying to an IFS, which keeps disk images in files, the disk-name is an IFS file name, and must conform to IFS's conventions.  If you copy a double disk filesystem referring to it as 'BFS', then CopyDisk will create one file containing both disk images.

Fine point for Dorado and D0 users:  'DP0' and 'DP1' refer to units 0 and 1 in the current partition.  'DP10' and 'DP11' refer to units 0 and 1 in partition 1 regardless of the current default partition; and similarly for 'DP20' and 'DP21'.  'BFS' and 'BFS0' refer to the Alto filesystem in the current partition; 'BFS1' to the filesystem in partition 1, etc.

.sec |The CopyDisk display|

CopyDisk displays a title line about one inch from the top of the screen, and below that the main display window, which consumes about half of the screen.  The main window is shared by the User and Server processes, only one of which is active at any time.  The process which currently owns the window identifies itself at the right side of the title line.  The title also shows the release date of the program and the Alto's name.  When a copy operation is in progress, the current disk address is displayed in the area above the title line.

When CopyDisk is started, the User is listening for commands from the keyboard and the Server is listening for connections from the network.  If you start typing commands, the User takes over control of the main window ('User' appears near the right end of the title line), and your commands and their responses are displayed there.  The Server refuses network connections while the User is active.  If another CopyDisk program connects to the Server, the Server takes over control of the main window ('Server' appears near the right end of the title line), and the Server logs its activity there.  The User ignores type-in (flashing the screen if any keys are typed) while the Server is active.

.sec |Keyboard Command Syntax|

CopyDisk's interactive command interpreter presents a user interface very similar to that of the Alto FTP subsystem.  The standard editing characters, command recognition features, and help facility (via "?") are available.

.ssec |Keyboard Commands|

.begin indent 5,5
.once indent 0
COPY
.continue
Starts a dialog to gather the information for copying a disk.  CopyDisk first asks for the name of the source disk by displaying "Copy from".  If the disk is local, it makes sure it is ready; if the disk is on another machine, it opens a connection and asks the remote machine if the disk is ready.  If you want to abort the connection attempt, hit the middle unmarked ('Chat') key.  If the source disk is ready, CopyDisk prompts you for the destination disk by displaying "Copy to", and then checks that that disk is ready also.  Next, it verifies that the disks are compatible, and depending on the disk type, may ask some questions about things peculiar to that disk (such as "Do all of the model 44?").  Then CopyDisk asks you to confirm your intention to overwrite the destination disk.  If you change your mind, type 'N' or <delete>.  If you respond yes, CopyDisk will pause for a few seconds, ignoring the keyboard, and then ask you to confirm once again.  Type-ahead does not work for this second confirmation.  This is your last chance to look at the disks and make sure that you are not overwriting the wrong one.  It happens!  This feature was in the original CopyDisk, was left out of the second version, and is back in this third version by popular demand from the many people who made that fatal mistake.

.once indent 0
QUIT
.continue
Terminates CopyDisk.  One of three things happens:

.begin indent 10,10,5
The Alto Exec is restarted if DP0 is ready, and has not been written on, and if CopyDisk was not booted from the net.

DP0 is booted if it is ready but has been written on or if CopyDisk was booted from the net.

NetExec is booted from the net if DP0 is not ready.
.end

All of this is attempting to leave the Alto running something useful.  If the disk in DP0 does not have an operating system on it when CopyDisk quits, the disk boot (option 2, above) will fail.  This will not hurt the disk, but you will have to boot manually.

.once indent 0
HELP
.continue
Displays a rather terse summary of how to use the program.

.once indent 0
LOGIN
.continue
Supplies any login parameters required by the remote server before it will permit copy operations.  CopyDisk will use the user name and password in the Operating System if they are there (they won't be if CopyDisk is booted from the net).  Logging into CopyDisk will set the user name and password in the OS (in the same manner as the Alto Executive's "Login" command.  This command is only meaningful when copying to or from an IFS; the Alto CopyDisk server ignores login parameters.

When you issue the LOGIN command, CopyDisk will first display the existing user name known to the OS.  If you now type a space, CopyDisk will prompt you for a password, whereas if you want to provide a different user name, you should first type that name (which will replace the previous one) followed by a space.  The command may be terminated by a carriage return after entering the user name to omit entering a password.

Ther parameters are not immediately checked for legality, but rather are sent to the server for checking when the next copy command is issued.  If a command is refused by the server because the name or password is incorrect, CopyDisk will prompt you as if you had issued the LOGIN command and then retry the command.

.once indent 0
CONNECT
.continue
Requests the remote CopyDisk server to 'connect' you to the specified directory on the remote system, i.e., to give you owner-like access to it.  The password may be omitted by typing carriage return after the directory name.  As with LOGIN, these parameters are not verified until the next transfer command is issued.  This command is only meaningful when copying to or from an IFS; the Alto CopyDisk server ignores connect requests.

.once indent 0
PARTITION
.continue
This command is only available on D0s and Dorados.  It prompts you for a partition number (for D0s in the range 1-2 for Dorados in the range 1-5), and sets the default partition.  It supplies as a default the current partition number, so you can find out where you are by saying 'Partition' and then typing carriage return.

.once indent 0
CHECK
.continue
Toggles the switch which controls whether a disk is checked after copying.  CopyDisk displays "on" if checking is now enabled, and "off" if it is now disabled.

.once indent 0
DEBUG
.continue
Toggles the switch which controls the display of debugging information.  The performance data presented at the end of this document is part of the debugging information; the network protocol interactions are displayed when this switch is set also.

.once indent 0
WRITEPROTECT
.continue
Toggles the switch which allows the network Server to write on local disks.  The default is that people can't overwrite your disk.

.once indent 0
COMPRESS
.continue
Toggles the switch which suppresses the transmission and checking of the data records of free pages.  This can significantly speed up network copies and reduce the size of disk images stored on IFSs.  The default is to compress.

.once indent 0
COMPARE
.continue
Compares two disks.  The dialog is very similar to the COPY command.  Neither disk is ever written.  This is useful to verify the health of your disk drive (but remember that it does not check the write logic).
.end

.sec |Command Line Syntax|

CopyDisk can also be controlled from the command line.  If there is anything in the command line except "CopyDisk" and global switches, the command line interpreter is started instead of the interactive keyboard interpreter.  Its operation is most easily explained by examples:

.ssec |Command line examples|

To copy DP0 to DP1:

.once indent 5,5
CopyDisk from DP0 to DP1

Note that 'from' and 'to' are optional (though stongly recommended for clarity), and one or both may be omitted or abbreviated:

.once indent 5,5
CopyDisk DP0 t DP1

is equivalent, though less obvious.

To copy the Basic non-programmer's disk from host 'Boggs' (which is running CopyDisk) onto a disk in your own machine:

.once indent 5,5
CopyDisk from [Boggs]DP0 to DP0

or, equivalently:

.once indent 5,5
CopyDisk from [3'#241'#]DP0 to DP0

The single quotes are necessary to keep the #s out of the clutches of the Alto Exec.  The quotes are not needed when typing to the keyboard interpreter.  Note that no spaces are allowed between the host name and the device name.

If the command line interpreter runs into trouble, it displays an error message and then starts the interactive interpreter.

.sec |Disk Errors|

Disk errors are termed 'soft' or 'hard' depending on whether retrying the operation corrects the difficulty.  If CopyDisk is still having trouble after many retries, it displays a message of the form "Hard error at DPn: cyl xxx hd y sec zz" in the main window and moves on.

Soft errors are not reported unless the debug switch is true, so as not to alarm users.  Their frequency depends on several factors.  Copying over the network will cause more soft errors then copying between two disks on the same machine.  Alto IIs get many more errors then Alto Is.  

During the Check pass, in addition to soft and hard errors, 'data compare' errors are also possible.  A data compare error means that the corresponding sections of the source and destination disks are not identical.  If any hard errors have been reported, then data compare errors are likely, otherwise getting data compare errors means that something is very wrong.  You should suspect the Alto.

Hard errors and data compare errors are serious, and you should not trust the copied pack if any are reported.  If the errors are on the source disk, try Scavenging it.  Bear in mind that there is some variance in alignment among disk drives, and that a pack which reads fine on one drive may have trouble on another.  Is the source disk in a different drive than where it is normally used?  Before allowing the Scavenger to rewrite sectors, consider that the pack may be OK, but the drive it is in may be out of alignment.  In this case, allowing the scavenger to rewrite the sectors is a bad idea.  If the errors are on the destination disk, try the copy again, and then suspect the pack or the disk drive itself.  If the destination pack was much colder than the temperature inside the drive, sectors written early in the copy pass may read incorrectly during the check pass.  It's a good idea to wait a few minutes for the pack to reach normal operating temperature before using it.

.sec |Creating a new disk|

Suppose you want to make a new disk by copying one of the 'Basic' disks.  There are three major ways to do this:

.begin indent 5,5,5
Put a blank disk in your Alto, and copy the basic disk from an IFS.  This is called the 'IFS copy' method.

Find an Alto with two disk drives and put a basic disk in one drive and a blank disk in the other.  This is called the 'double disk copy' method.

Find two Altos, each with one drive, that are connected by a network and put a basic disk in one Alto and a blank disk in the other.  This is called the 'network copy' method.
.end

Having decided on one of the above methods, you must now get CopyDisk running on the Alto(s).  There are two major ways to do this:

.begin indent 5,5,5
Start CopyDisk from a disk which has 'CopyDisk.run' on it.

Boot CopyDisk over the network from a 'Boot Server'.
.end

.ssec |Starting CopyDisk from another Disk|

If you do not have access to a Boot Server, you must start CopyDisk from a disk that has it on it.  Put a disk with CopyDisk on it into the Alto and type "CopyDisk<return>".  Then switch disks.  BE CAREFUL!!  People sometimes forget to switch disks at this point and accidentally copy the wrong one.  This is why CopyDisk asks you to confirm your intentions so many times.

.ssec |Booting Copydisk from the net|

The best way to start CopyDisk is to boot it from the network.  That way you are more likely to get the latest version, and you avoid the pitfall mentioned above.  Of course, you must have network access to a Boot Server.  Most Gateways have Boot Servers.  If this method doesn't seem to work, you will have to fall back to starting CopyDisk from another disk.

Hold down the <BS> and <Quote> keys while pressing the boot button on the Alto.  You must continue to hold down <BS> and <Quote> (but let go of the boot button!) until a small square appears in the middle of the screen.  This can take up to 30 seconds, but usually happens in less than 5 seconds.  You are now taking to the NetExec (see the documentation in the Subsystems manual if you are curious), and you should type "CopyDisk<return>".  The screen will go blank, the little square will appear again (you don't have to hold down any keys this time), and soon CopyDisk should appear on the screen.

.ssec |The IFS Copy Method|

Put a blank disk in DP0.  Type "Copy<space>", and when it says "from" type a name of the form: [IFS-name]File-name, where 'IFS-name' is the name of your local IFS (such as 'Ivy', which is the name of my IFS), and 'File-name' is the name of the file on which the basic disk is kept.  This may be installation-dependent; here at Parc the basic non-programmers disk is called '<BasicDisks>NonProg.disk', so to get a copy of that disk I would type "[Ivy]<BasicDisks>NonProg.disk".  When CopyDisk says "Copy to" type "DP0<return>".  Then type <return> each time it asks for confirmation.  Some numbers will appear in the top center of the screen.  When they disappear, CopyDisk is done.  Type "Quit<return>".  It will boot the disk, and you should find yourself talking to the Alto Exec.

.ssec |The Double-Disk Copy Method|

Put the basic disk in DP0 and put your disk in DP1.  Type "Copy<space>", and when it says "from" type DP0<return>.  When it says "Copy to", type "DP1<return>".  Then type <return> each time it asks for confirmation.  Some numbers will appear in the top center of the screen.  When they disappear, CopyDisk is done.  Type "Quit<return>".  Put the basic disk back where it belongs, and take your disk with you.

.ssec |The Network Copy Method|

It doesn't matter which Alto you type commands to.  Assume that the basic disk is in the Alto called "Tape-Controller", your disk is in the Alto called "Myrddin" and you are going to type commands to Tape-Controller.  Type "Copy<space>", and when it says "from" type "DP0<return>".  When it says "Copy to", type "[Myrddin]DP0<return>".  Then type <return> each time it asks for confirmation.  Some numbers will appear in the top center of the screen.  When they disappear, CopyDisk is done.  Type "Quit<return>", and put the basic disk back in the rack.  Go to Myrddin and type "Quit<return>".  It will boot the disk, and you should find yourself talking to the Alto Exec.

.sec |Performance|

This section calculates the times to copy disks under different conditions.  CopyDisk times its operations and displays the results if the debug switch is set, so you can compare the numbers derived here with reality.

.ssec |TSweep|

First, we calculate TSweep, the time to read or write a disk assuming that we can consume or produce data faster than the disk.  This best possible case is the sum of two terms.  The first term is the time necessary to sweep an active read/write head over every sector on the disk:

.once center
Rot * nCyl * nHds.

The second term is the time lost while seeking to the next cylinder.  We assume that these seeks take less than one rotation but that a whole rotation is lost:

.once center
Rot * nCyl.

Combining, we get:

.once center
TSweep = Rot * nCyl * (nHds+1).

.begin nofill tabs 10

where:\Rot is the rotation time of the disk in seconds
\nCyl is the number of cylinders, and
\nHds is the number of heads.
.end

.ssec |Disk-To-Disk Copy|

By disk-to-disk copy we mean copying from one disk to another on the same machine, using a single controller and not overlapping seeks.  The fastest way to do this is to read the entire source disk into memory, switch to the destination disk, and then write it all.  The switch from the source to the destination disk, will lose on the average half a revolution while waiting for the right sector on the new disk to come under a head.  Neglecting the switch time which is small compared to the other two terms, the best possible disk-to-disk copy time is 2 * TSweep.

With limited memory, the best we can do is fill all available memory buffers reading the source disk, switch disks, write them onto the destination disk, and then switch back to the source disk for another load.  In this case we can't ignore the switch time, which is the total number of sectors on the disk divided by the number of sector buffers times the rotation time of the disk:

.skip once center
Rot * (nCyl * nHds * nSec)/nBuf

.begin nofill tabs 10

where\nSec is the number of sectors per track, and
\nBuf is the number of memory buffers.
.end

So the disk-to-disk copy time, TDDCopy, is:

.skip once center
TDDCopy = 2 * TSweep + Rot * (nCyl * nHds * nSec)/nBuf

.ssec |Net Copy|

By net copy we mean copying from a disk on one machine through a network to a disk on another machine.  In this case the disk controllers can be going in parallel, and the factor of two in the first term of TDDCopy vanishes.  In additon, if the bandwidth of the network connection is higher than the transfer rate of the disks so that as soon as a sector is read from the disk it is sent out of the machine, the memory limitation goes away and the second term of TDDCopy vanishes.

The CopyDisk network protocol sends a small amount of information along with each sector which must be factored into the calculation of the bandwidth needed to run without memory limitation.  Note that the bandwidth we are concerned with here is that perceived by a client of the network services:  user data bits per second, not raw bits per second through the network hardware.

If the network is slower than the disks, then the time to copy a disk is the time required to transmit all of the bits on a disk plus the protocol overhead bits:

.skip once center
TNetCopy = nCyl * nHds * nSec * (sB + sOv)/bwNet

.begin nofill tabs 10

where\sB is the bits of disk information per sector,
\sOv is the CopyDisk protocol overhead per sector, and
\bwNet is the bandwidth of the network connection.
.end

The bandwidth of the network connection is hard to state, and depends on a number of factors.  Here are a few:

.begin indent 5,5
Reduction of the emulator's instruction execution rate due to interference from the disk and network hardware.

Reduction of the amount of the emulator cycles available to the network and disk code due to mutual interference.

Reduction of the peak network bandwith due to interference from other hosts on the network.
.end

The minimum network bandwith required to copy a disk at full speed is:

.skip once center
MinBwNet = 16 * nCyl * nHds * nSec * (sB + sOv)/TSweep.

.ssec |The Numbers for Altos|

Here are the relevant numbers for the disks which this program can copy:

.begin group nofill tabs 15,30,45,60,75

\Diablo-31\Diablo-44\Trident-80\Trident-300

Rot (ms)\40\25\16.66\16.66
nCyl\203\406\815\815
nHds\2\2\5\19
nSec\12\12\9\9

sB\266\266\1036\1036
sOv\2\2\2\2
nBuf\80\80\18\18
.end

.ssec |Reality|

Here are the results of plugging the numbers into the equations, and comparing them against actual measurements.  The format is predicted(measured).  NA means not available.

.begin group nofill tabs 15,30,45,60,75

\Diablo-31\Diablo-44\Trident-80\Trident-300

TSweep\0:24\0:30\1:21\4:32
TDDCopy\0:51(0:51)\1:04(1:16)\3:18(3:31)\11:20(19:27)
TNetCopy\(1:05)\(2:16)\(26:31)\(NA)

bwNet\(323 Kb/s)\(308 Kb/s)\(383 Kb/s)\(NA)
MinBwNet\859 Kb/s\1.375 Mb/s\7.520 Mb/s\8.509 Mb/s
.end

.sec |Revision History|

August 7, 1977
.break
First relese.

August 28, 1977
.break
Soft errors are only reported if the debug switch is set.  Data compare errors now display the offending disk address.  VERIFY and WRITEPROTECT commands added to keyboard command interpreter.  Write protect global switch added.

October 16, 1977
.break
More microcode to speed things up

October 27, 1977
.break
Bug fixes.

December 18, 1977
.break
Fixed a bug which prevented it from copying the second half of a two disk file system.  The network format for Diablo disks changed.

March 22, 1978
.break
CopyDisk will now do the right thing for "[thisHost]device".  The default value of WRITEPROTECT is now TRUE.

October 27, 1978
.break
Internal reorganization -- no external changes.

December 12, 1978
.break
Fix bug in Copying T-300s.

September 10, 1979
.break
Reload with current packages.

April 26, 1980
.break
Network protocol extended to speak to IFSs.  Much internal work, but very little visible change.  PARTITION and HELP commands added.  VERIFY command renamed COMPARE

November 12, 1980
.break
BFS protocol extended to handle multiple disk file systems.  Referring to a file system as 'BFS' will cause both disks to be copied automatically.  CopyDisk now works on Shugarts emulating Tridents.