tags:

views:

2240

answers:

9

Some commands in Solaris (such as iostat) report disk related information using disk names such as sd0 or sdd2. Is there a consistent way to map these names back to the standard /dev/dsk/c?t?d?s? disk names in Solaris?

Edit: As Amit points out, iostat -n produces device names such as eg c0t0d0s0 instead of sd0. But how do I found out that sd0 actually is c0t0d0s0? I'm looking for something that produces a list like this:

sd0=/dev/dsk/c0t0d0s0
...
sdd2=/dev/dsk/c1t0d0s4
...
Maybe I could run iostat twice (with and without -n) and then join up the results and hope that the number of lines and device sorting produced by iostat is identical between the two runs?

+1  A: 

Try using the '-n' switch. For eg. 'iostat -n'

Amit
A: 

sd0 sdd0 are instance names of devices.. you can check /etc/path_to_inst to get instance name mapping to physical device name, then check link in /dev/dsk (to which physical device it is pointing) it is 100% sure method, though i dont know how to code it ;)

+2  A: 

Following Amit's idea to answer my own question, this is what I have come up with:

iostat -x|tail -n +3|awk '{print $1}'>/tmp/f0.txt.$$
iostat -nx|tail -n +3|awk '{print "/dev/dsk/"$11}'>/tmp/f1.txt.$$
paste -d= /tmp/f[01].txt.$$
rm /tmp/f[01].txt.$$

Running this on a Solaris 10 server gives the following output:

sd0=/dev/dsk/c0t0d0
sd1=/dev/dsk/c0t1d0
sd4=/dev/dsk/c0t4d0
sd6=/dev/dsk/c0t6d0
sd15=/dev/dsk/c1t0d0
sd16=/dev/dsk/c1t1d0
sd21=/dev/dsk/c1t6d0
ssd0=/dev/dsk/c2t1d0
ssd1=/dev/dsk/c3t5d0
ssd3=/dev/dsk/c3t6d0
ssd4=/dev/dsk/c3t22d0
ssd5=/dev/dsk/c3t20d0
ssd7=/dev/dsk/c3t21d0
ssd8=/dev/dsk/c3t2d0
ssd18=/dev/dsk/c3t3d0
ssd19=/dev/dsk/c3t4d0
ssd28=/dev/dsk/c3t0d0
ssd29=/dev/dsk/c3t18d0
ssd30=/dev/dsk/c3t17d0
ssd32=/dev/dsk/c3t16d0
ssd33=/dev/dsk/c3t19d0
ssd34=/dev/dsk/c3t1d0

The solution is not very elegant (it's not a one-liner), but it seems to work.

Erlend Leganger
This works very well.
jasonjwwilliams
You can collapse this all into one (bash) command and avoid any temporary files: `paste -d= <(iostat -x | tail -n +3 | awk '{print $1}') <(iostat -nx | tail -n +3 | awk '{print "/dev/dsk/"$11}')`
Tekhne
A: 

Any idea about how to do that within dtrace (iotop) ?

Benoît
A: 

I found this snippet on the internet some time ago, and it does the trick. This was on Solaris 8:

#!/bin/sh
cd /dev/rdsk
/usr/bin/ls -l *s0 | tee /tmp/d1c |awk '{print "/usr/bin/ls -l "$11}' | \
sh | awk '{print "sd" substr($0,38,4)/8}' >/tmp/d1d
awk '{print substr($9,1,6)}' /tmp/d1c |paste - /tmp/d1d
rm /tmp/d1[cd]
Bob
A: 

A slight variation to allow for disk names that are longer than 8 characters (encountered when dealing with disk arrays on a SAN)

!/bin/sh

cd /dev/rdsk /usr/bin/ls -l *s0 | tee /tmp/d1c | awk '{print "/usr/bin/ls -l "$11}' | \ sh | awk '{print "sd" substr($0,38,4)/8}' >/tmp/d1d awk '{print substr($9,1,index($9,"s0)-1)}' /tmp/d1c | paste - /tmp/d1d rm /tmp/d1[cd]

+2  A: 

I found the following in the Solaris Transistion Guide:

"Instance Names

Instance names refer to the nth device in the system (for example, sd20).

Instance names are occasionally reported in driver error messages. You can determine the binding of an instance name to a physical name by looking at dmesg(1M) output, as in the following example.

sd9 at esp2: target 1 lun 1 sd9 is /sbus@1,f8000000/esp@0,800000/sd@1,0

Once the instance name has been assigned to a device, it remains bound to that device.

Instance numbers are encoded in a device's minor number. To keep instance numbers consistent across reboots, the system records them in the /etc/path_to_inst file. This file is read only at boot time, and is currently updated by the add_drv(1M) and drvconf"

So based upon that, I wrote the following script:

for device in /dev/dsk/*s2

do

dpath="$(ls -l $device | nawk '{print $11}')"

dpath="${dpath#*devices/}"

dpath="${dpath%:*}"

iname="$(nawk -v dpath=$dpath '{

    if ($0 ~ dpath) {

        gsub("\"", "", $3)

        print $3 $2

    }

}' /etc/path_to_inst)"

echo "$(basename ${device}) = ${iname}"

done

By reading the information directly out of the path_to_inst file, we are allowing for adding and deleting devices, which will skew the instance numbers if you simply count the instances in the /devices directory tree.
+2  A: 

As pointed out in other answers, you can map the device name back to the instance name via the device path and information contained in */etc/path_to_inst*. Here is a Perl script that will accomplish the task:

#!/usr/bin/env perl

use strict;

my @path_to_inst = qx#cat /etc/path_to_inst#;
map {s/"//g} @path_to_inst;
my ($device, $path, @instances);

for my $line (qx#ls -l /dev/dsk/*s2#) {
    ($device, $path) = (split(/\s+/, $line))[-3, -1];
    $path =~ s#.*/devices(.*):c#$1#;

    @instances =
        map {join("", (split /\s+/)[-1, -2])}
            grep {/$path/} @path_to_inst;
*emphasized text*
    for my $instance (@instances) {
        print "$device $instance\n";
    }
}
A: 

One liner version of the accepted answer (I only have 1 reputation so I can't post a comment):

paste -d= <(iostat -x | awk '{print $1}') <(iostat -xn | awk '{print $NF}') | tail -n +3