Defining Disk Geometry and Partitioning

Introduction

This is a simple program which uses a CLOS object hierarchy to describe computer hard disks on a UNIX or UNIX-like operating system.

The program is intended to provide an initial representation of disks which can be extended and improved; see the suggestions for improvements later in this document.

Disk Geometry

The root class in the object hierarchy is disks-package-object; this is internal to the package and is not exported. It's immediate sub-classes however are exported. The first of these is disk-geometry, which describes the physical characteristics of a (type-of) disk. Here are brief definitions of some useful terms:

platter
Disks are made up of a number of circular platters, each of which is has a magnetic coating. The platters are stacked one on top of another and rotate together round a central spindle. Data is read from and written to these using a number of read/write heads each of which is attached to an arm which can be moved in order to access different parts of the disk.
sector
This is the smallest unit of storage on the disk which the system can access, and is typically 512 bytes.
track
A track is a series of sectors, on the same physical platter of a disk, all of which can be accessed without moving the disk's read/write heads.
cylinder
A cylinder is the set of tracks, each of which is on a different platter and all of which can be accessed without moving the disks's read/write heads. When a disk is divided into different logical partitions (or slices), these are specified in terms of the start cylinder of each partition plus the number of cylinders it contains. Typically some small number of cylinders is reserved i.e. not available to the system for use within disk partitions.

The slots in the disk-geometry object are used to store various information as follows:

nametag
A name which is used by the program to refer to this instance of disk-geometry.
bytes/sector
The number of bytes per sector (typically 512).
sectors/track
The number of sectors in each track.
tracks/cylinder
The number of tracks in a cylinder.
sectors/cylinder
The number of sectors in a cylinder; this is calculated from sectors/track and tracks/cylinder when the instance is created.
bytes/cylinder
The number of bytes in a cylinder; this is calculated and cached - as an example of how to do this - the first time the slot-value is accessed.
cylinders
The total number of cylinders on the disk, including both accessible and reserved cylinders.
reserve-cylinders
The number of reserved cylinders.
accessible-cylinders
The number of accessible (usable) cylinders, calculated as the difference between cylinders and reserve-cylinders when the instance is created.

Note that not all of these are used in the program as it stands (except when it comes to printing out details of an instance); however they exist to make it easier to write extensions to the program, as well as to serve as examples.

Disk Partitioning

Another immediate subclass of disk-package-object is disk-partition. This is used to specify a partition map for a particular disk.

Typically, a map will divide a disk into a maximum of 7 slices; slices are numbered from 0, with slice 2 (by convention and for historical reasons) being used to reference the whole disk.

A possible partition map therefore for a disk with a total of 17660 usable cylinders might look like this.

Slice Start Cylinder End Cylinder # of Cylinders
0 0 130 131
1 131 228 98
2 0 17659 17660
3 229 749 521
4 0 0 0
5 750 847 98
6 848 2668 1821
7 2669 17659 14991

In this map, the disk is divided into 6 consecutive slices: slices 0, 1, 3, 5, 6 and 7. Slice 2 is the whole disk, and slice 4 is not needed: note the convention of specifying both start cylinder and number of cylinders as 0 to indicate an unused slice. Note also that only the start cylinder and number of cylinders is needed to specify the extent of a slice completely: the end cylinder is included in this example for clarity.

The slots in the disk-partition object are as follows:

nametag
A name which is used by the program to refer to this instance of disk-partition.
slice0
Start cylinder and # of cylinders for slice 0
slice1
Start cylinder and # of cylinders for slice 1
slice2
Start cylinder and # of cylinders for slice 2
slice3
Start cylinder and # of cylinders for slice 3
slice4
Start cylinder and # of cylinders for slice 4
slice5
Start cylinder and # of cylinders for slice 5
slice6
Start cylinder and # of cylinders for slice 6
slice7
Start cylinder and # of cylinders for slice 7

Disks

The last immediate sub-class of disks-package-object provided is disk. An instance of disk is simply an association between an instance of disk-geometry, which specifies the physical characteristics of the disk, and an instance of disk-partition, which specifies an appropriate partition map.

The slots of disk are as follows:

nametag
A name which is used by the program to refer to this instance of disk.
geometry
An instance of disk-geometry
partition
An instance of disk-partition

Creating Disk Package Objects

Some simple macros are provided to define new instances of disk, disk-geometry and disk-partition.

To define a new instance of disk, call (define-disk disk-name geometry-name partition-name). If no geometry or partition objects exist with the given names, new ones are created with the names provided. All three name arguments are optional; if a name isn't provided, then the macro will create new instances.

New instances of disk-geometry and disk-partition are created using macros define-disk-geometry and define-disk-partition respectively. All three defining forms will prompt the user to supply necessary information for slot values if it is needed and not provided as arguments; some elementary sanity checks on the data are also carried out using after methods on initialize-instance.

Verbose Mode

The package exports a *verbose* symbol; if the value of this is t, the defining forms and after methods print out detailed information when creating instances of disk package objects. Set this to nil if you want only to hear about important errors or warnings.

Internal Package Functionality

For each immediate sub-class of disk-package-object, a function which returns an instance of that class given its name is provided as an internal function within the package (e.g. get-geometry); for each type a mapping function is also provided.

There are also output routines, such as the generic function print-details, which prints out the slot values for a disk-package-object.

Extending/Improving the Program

Here we suggest briefly some possible extensions and improvements.

The program calls internal functions such as map-over-geometry-list and get-geometry etc. to access instances of sub-classes of disks-package-object.

If similar functionality were provided through external generic functions specialised on these sub-classes, it would probably be useful in itself, as well as providing a more general and extensible mechanism. The program could therefore be improved by replacing these functions with improved generic functions and methods, and exporting these.

The output routines could also be improved or replaced. One possibility is to provide output routines which use graphics routines to print out more helpful representations of disks, partition maps and so on.

As it stands the program will let you define more than one instance of a given class with the same name, but e.g. define-disk will only look up the LATEST definition with a given name. You could easily improve on this behaviour.

Currently there are provided only the basic subclasses disk-geometry, disk-partition and disk. These themselves could be subclassed, e.g. to define a hierarchy of physical disk types under disk-geometry, or a class of disks with a particular geometry and a default partition map. A standard partition map could be implemented. One further possibility is to define a default map as the value of a slot in disk-geometry; then a specific instance of disk either uses the default map or replaces this with its own map. If you do decide to extend the hierarchy, consider carefully the effect on the defining forms provided.

There are currently no functions to help the user define a partition map, which requires a bit of arithmetic - an ideal task for a computer. What about implementing an additional option to print-details which provides the equivalent disk space in megabytes (which is what system administrators are more interested in) for partition maps?

And what about implementing a function which allows the user to designate one slice as the "free hog" and have it use all space which is not taken up the by the rest? How about providing a function which aids the user in defining a map by printing out running totals - this could allow the user to enter sizes in cylinders or (approximate) megabytes? There are many other possibilities...

Author: Gail Anderson (ga@cley.com), Cley Limited.
Copyright 1999–2003 Cley Ltd. & Franz Inc.