Jul 00 Challenge
Volume Number: 16
Issue Number: 7
Column Tag: Programming
Programmer's Challenge
by Bob Boonstra, Westford, MA
RAID-5+
Those of you in the Information Systems business have certainly heard of Redundant
Array of Independent (or Inexpensive) Disks, or RAID technology. As the name
suggests, RAID stores data across multiple disks to provide improved performance and
some level of protection against disk failure. Several RAID levels have been
implemented, and one of the most common, RAID Level 5, employs disk striping
(spreading blocks of data across multiple disks) and parity to optimize disk access for
applications that perform random small read/write operations, and to protect against
the failure of a single disk.
Our Challenge application, however, is a little more demanding. We're operating a
mission critical application, one that cannot afford to lose data even with a double
hardware failure. Your Challenge is to implement a RAID-5+ system that has the
performance advantages of RAID 5, but can continue functioning when two disk drives
fail.
The prototype for the code you should write is:
/*
* ReadProc and WriteProc are callbacks that allow you to write to
multiple drives
* simultaneously, simulating the effect of striping.
*/
typedef void (* WriteProc) (/* conduct physical writes to multiple
drives */
long startByte[], /* start write from startbyte[n] physical byte
on disk n */
long numBytes[], /* write numbytes[n] bytes from disk n */
char *writeBuffer[], /* write to buffer[n] from disk n */
Boolean readErr[]
/* returns writeErr[n]==true if disk n has a write error or
parameters were bad */
);
typedef void (* ReadProc) (/* conduct physical reads from multiple
drives */
long startByte[], /* start read from startbyte[n] physical
byte on disk n */
/* bytes startByte..startByte+numBytes-1 must be
within 0..diskSize-1 */
long numBytes[], /* read numbytes[n] bytes from disk n */
char *readBuffer[], /* read into buffer[n] from disk n */
Boolean readErr[]
/* returns readErr[n]==true if disk n has a read error or
parameters were bad */
);
/*
* InitRaid provides the problem parameters
*/
void InitRaid(
long numDisks,
/* problem size, you will have numDisks of real data, plus 2
disks for parity */
long diskSize, /* number of bytes in each disk */
long failureRate, /* expect 1 failure in each failureRate
read/write attempts */
WriteProc physicalWrite,
/* procedure that allows you to write to numDisks+2 disks of
size diskSize */
ReadProc physicalRead
/* procedure that allows you to read from numDisks+2 disks
of size diskSize */
);
void RepairDisk(
long whichDisk /* index of disk that has been repaired, no more
than 2 at one time */
);
/*
* RaidWrite and RaidRead ask you to write to the numDisks*diskSize
bytes of
* storage. You use WriteProc and Read proc to actually write to the
(numDisks+2)
* physical devices, using redundant writes to compensate for the
loss of up to two
* disks. RaidWrite and RaidRead bytes are numbered
0..numDisks*diskSize-1.
* RaidWrite and RaidRead return true unless there is a problem
performing the
* write/read.
*/
Boolean RaidWrite(
long startByte, /* write starting at this byte */
long numBytes, /* number of bytes to write */
char *buffer [TOKEN:12074] write bytes from this
buffer */
);
Boolean RaidRead(
long startByte, /* read starting at this byte */
long numBytes, /* number of bytes to read */
char *buffer [TOKEN:12074] read bytes into this buffer
*/
);
void TermRaid(void);
This Challenge starts with a call to your InitRaid routine. InitRaid is provided with the