Now that we know a bit more about SCSI, let's see how the system refers to the devices once they are connected and how they are made available for us to use.
Solaris devices are located in two main directories—/dev and /devices—and appear in these as files in the filesystem, just as any other file or directory would. The difference between the two directories is that /devices contains “physical” device entries, while /dev contains “logical” device entries. Let's look at what these are in more detail.
When devices are connected to the system they are added to its device tree. This is a list, generated by the OpenBoot PROM at boot-time, of all the connected hardware. The list is stored in memory as a tree hierarchy, much like the structure of the UNIX filesystem. The tree is built by equating the “root” entry to the main system board then using the directories of the tree to describe individual pieces of hardware or controllers connected to hardware. Let's look at an example of this to explain it better.
Let's assume that two disks are connected to the system, each via their own host adaptor (which have their own SCSI controller onboard). We know that the host adaptor connects to the system board, and the disk (via its onboard controller) is connected to the host adaptor. The tree that represents the series of connections would look like the one shown in Figure 17.2.
By following the tree through each hardware node, we can define a path to the device, which for the two disks in the tree above would be as follows:
/host_adaptor1/disk_controller/disk1 /host_adaptor2/disk_controller/disk2
These are known as the “physical device names” and are the type of entries that are stored in the /devices directory. We don't need to be too concerned about the entries here because /devices is maintained and used by the kernel.
Physical device names aren't very user-friendly, so a logical device is available for every physical one. These are placed in the /dev directory and linked back to the physical device entry in /devices. The naming convention used for each one depends on the type of device itself; for example, the disk entries are quite different from the tape ones.
An instance name is also allocated to each device by the kernel. It does this so that instead of having to deal with awkward physical names, such as “/host_adaptor1/disk_controller/disk1,” it can use an abbreviation, for example “sd0.” We'll see lots of examples of this in the output from prtconf and the system bootup messages.
Solaris disks have two entries in the /dev directory. The reason for this is that each disk can be accessed in two ways: either as a “block” device or a “character” device. The block device retrieves buffered data, in chunks of the block size, and is used by programs such as df and mount. The character device, also known as the “raw device,” is used for retrieving unbuffered data, generally a character at a time, and is used by programs such as dd and fsck.
The entries for the block devices are created in /dev/dsk, while the raw devices are created in /dev/rdsk. The name given to each disk is based on the controller number (host adaptor instance), SCSI ID of the target, and the LUN number. For example, later we'll connect a disk, set to SCSI ID 2, to controller 1. It doesn't contain any LUNs, so this is in effect LUN 0. Therefore the disk itself is named c1t2d0. But, as we saw in Chapter 6, “The Filesystem and Its Contents,” each disk can be partitioned into up to seven slices, so files are also created under /dev to allow each individual disk slice to be referenced. Therefore, for each disk the following files will exist in the directories /dev/dsk and /dev/rdsk:
c1t2d0
c1t2d0s0
c1t2d0s1
c1t2d0s2
c1t2d0s3
c1t2d0s4
c1t2d0s5
c1t2d0s6
c1t2d0s7
The name c1t2d0 refers to the whole disk and so does c1t2d0s2 because slice two always represents the whole disk. Each of the other names simply refers to the section of the disk that is defined as that slice in the disk VTOC (Volume Table Of Contents).
The logical names for tape drives are much easier to understand. First, since the tape drive is a raw device only, the filenames are all placed in one subdirectory named rmt. Next, they are simply numbered sequentially—0 is the first tape, 1 the next, and so on.
Each tape drive allows data to be written slightly differently, including various compression ratios, rewind or no-rewind options, and so forth. To allow these different options, a number of devices are provided. For example, for the first tape drive, we see the following logical devices in /dev/rmt:
helium# cd /dev/rmt helium# ls 0 0c 0cn 0hbn 0lb 0m 0mn 0ub 0b 0cb 0h 0hn 0lbn 0mb 0n 0ubn 0bn 0cbn 0hb 0l 0ln 0mbn 0u 0un helium#
Each of these relate to the various options. For example, “0c” is a high-compression device, whereas “0cn” is the same device but doesn't rewind automatically.
During the boot process, after the device tree has been built, the system will allocate an instance number to every device and create the physical and logical device entries. This is great when a new device has just been added, but we also need to make sure that the same device retains the same instance number and logical device name across any subsequent reboots. We can't have a disk being seen as the first disk one time, and the second disk another time!
To do this, the kernel uses a file named /etc/path_to_inst to provide a mapping between the instance number allocated to a device and its physical name. This is consulted at boot-time to see which instance numbers should be allocated to which devices.