[Search for users] [Overall Top Noters] [List of all Conferences] [Download this site]

Conference turris::digital_unix

Title:DIGITAL UNIX(FORMERLY KNOWN AS DEC OSF/1)
Notice:Welcome to the Digital UNIX Conference
Moderator:SMURF::DENHAM
Created:Thu Mar 16 1995
Last Modified:Fri Jun 06 1997
Last Successful Update:Fri Jun 06 1997
Number of topics:10068
Total number of notes:35879

9441.0. "How to associate "cam0" with "rz1"?" by CLARID::KREYER (Andre KREYER, Sophia Antipolis (FR)) Wed Apr 09 1997 06:34

	Hello,
	
	I've inherited a piece of C code that walks down the configuration
	elements using getsysinfo with GSI_BUS_STRUC, GSI_CTLR_STRUC and
	GSI_DEV_STRUC. This eventually leads me down to disk/tape devices
	where I use IOCTL to get the device type (RZ26 for example).
	
	1) Is there any other way to get the device type that does not
	   require SU privilege (which is required by IOCTL)?
	   
	2) The code worked fine until around V3.2G. Since then rather than
	   finding a "rz1" device from the call to GSI_DEV_STRUC, it now
	   comes back with "cam0". How can I convert this "cam0" back to
	   "rz1"?

	Thanks in advance for any help on those questions.
	
								.Andre. 

T.RTitleUserPersonal
Name
DateLines
9441.1SSDEVO::ROLLOWDr. File System's Home for Wayward Inodes.Wed Apr 09 1997 11:1919
	You might want to look at the unit and logunit fields of
	the device structure to see if they match numbers that
	are some combination of the bus, target and LUN number 
	for SCSI devices.  If so that leads to a possibility for
	getting the device type, though its is messy and still
	requires running setuid as kmem.

	If you have the bus, target and LUN number it should be
	possible to wind your way through the SCSI CAM driver
	data structures in the hope that they keep a copy of the
	device type string from the cam_data.c entry or an equivalent.
	At the least the driver may keep a copy of the Inquiry data.
	But, you need read access to /dev/kmem for this.  And the
	data structure got considerably more complicated in V4.0.

	If you end up having to run setuid root or making the
	user run as root, then there are lots of ways of getting
	the device type from the bus/target/LUN, the easiest being
	the DEVIOCGET I/O control
9441.2Sorry, I'm lost...CLARID::KREYERAndre KREYER, Sophia Antipolis (FR)Thu Apr 10 1997 05:1081
	Alan,
	
	Thanks for the info you provide. I must however confess that most
	of what you said I can hardly make use of since my Digital UNIX
	internals understanding is probably as close to NULL as it ever
	can get :-) But I'm willing to improve...

	What follows is 2 extracts of data collected from systems running
	OSF1 V3.2 and V4.0 which probably better explain what .0 meant:


-------------- OS version:                    OSF1 V3.2 -----------------------
 
bus pci0 on nexus is alive (PCI bus)
bus psiop0 on pci0 is alive (SCSI busses)
controller scsi0 (SCSI) on psiop0 is alive
device rz0 (RZ26L) on scsi0 is alive   <---------
device rz4 (RRD43) on scsi0 is alive   <--------- This is what I need
device rz1 (RZ28) on scsi0 is alive    <---------
bus isa0 on psiop0 is alive (ISA bus)

		--- Extract of most recent UERF boot record ---  
 
                                        scsi0 at psiop0 
                                        rz0 at scsi0 bus 0 target 0 lun 0 (DEC 
                                         _    RZ26L    (C) DEC 442D) 
                                        rz4 at scsi0 bus 0 target 4 lun 0 (DEC 
                                         _    RRD43   (C) DEC  1084) 


-------------- OS version:                    OSF1 V4.0 -----------------------
 
bus tc0 on nexus is alive (Turbo Channel bus)
bus tcds0 on tc0 is alive (PMAZ-xS|PMAZx)
controller scsi0 (SCSI bus) on tcds0 is alive
device cam0 (Unidentified) on scsi0 is alive  <------
device cam1 (Unidentified) on scsi0 is alive  <------
device cam2 (Unidentified) on scsi0 is alive  <------ This is what I would
device cam3 (Unidentified) on scsi0 is alive  <------ like to fix...
device cam4 (Unidentified) on scsi0 is alive  <------
controller scsi1 (SCSI bus) on tcds0 is alive
device cam5 (Unidentified) on scsi1 is alive  <------
 
		--- Extract of most recent UERF boot record ---  
 
                                        scsi0 at tcds0 slot 0 
                                        rz1 at scsi0 target 1 lun 0 (LID=0) 
                                         _(DEC     RZ26     (C) DEC T392) 
                                        rz2 at scsi0 target 2 lun 0 (LID=1) 
                                         _(DEC     RZ26     (C) DEC T392) 
                                        rz3 at scsi0 target 3 lun 0 (LID=2) 
                                         _(DEC     RZ26     (C) DEC T392) 
                                        rz4 at scsi0 target 4 lun 0 (LID=3) 
                                         _(DEC     RRD43   (C) DEC  0064) 
                                        rz6 at scsi0 target 6 lun 0 (LID=4) 
                                         _(DEC     RZ28     (C) DEC 435E) 


	It looks like UERF has part of a response to the question since it
	provides a LID=x parameter which seems to correspond to the "CAMx"
	device. Is that assumption correct? If it is, how does it work?
	Where/what can I read that talks about this subject?

	In fact what I need to provide in the report could be either form:
device cam0 (RZ26) on scsi0 is alive		<-- Acceptable
device rz1 (RZ26) on scsi0 is alive		<-- OK
device cam0 -> rz1 (RZ26) on scsi0 is alive	<-- Excellent
	At the moment, the real important data item I miss is the device
	type since associating a real hardware option name (PMAZ) with a
	logical device name (tcds0) is the added value my tool is supposed
	to provide...

								.Andre.

P.S:	Suggesting to use UERF output is not acceptable, because for some
	reasons (which I don't understand) that output misses devices on
	both systems (rz1 on 3.2 and cam5 on 4.0), too bad...



9441.3NABETH::alanDr. File System&#039;s Home for Wayward Inodes.Thu Apr 10 1997 19:1736
	As far as I know the structures accessed by getsysinfo(2) have
	no way of directly accessing the SCSI Inquiry data for a SCSI
	devices.  This is the information that the device type in it;
	RZ26, TZ88, TL800, etc.  Back when the GSI_DEV_NAME feature
	of getsysinfo(2) would use device mnemonics such as "rz" and
	"tz" it was possible to construct enough device name, together
	with the logunit field of the device structure, to open the
	corresponding in /dev and use the DEVIOCGET I/O control to
	get the device type.  With GSI_DEV_NAME putting in "cam" it
	becomes much harder to get the desired information.

	As it happens, one of the other fields in the device structure
	is one called "unit", which is described as the "physical unit
	number".  It is possible that this number is an encoding of
	the SCSI Bus, target and logical unit numbers for the device.
	Given that information it is possible to work out the device
	name as before if you can figure out what the general device
	type is; disk, tape, etc.  I think the string at the end of
	"dev_type" is this bit of information, but that string is in
	kernel space and you need to read from kernel memory to get
	it.

	Or, using the CAM User Agent, you can send an Inquiry command
	to the device and find out what the device calls itself.

	The bottom line though is that you have to be root to get
	any sort of remotely useful information out of this interface
	except the very basic bus/controller/device organization of
	the system.

	Maybe this is one of the things that will be fixed in the
	mythical Steel release...  If not, you'll need to submit a
	QAR and hope it gets fixed sometime in the next two or 
	three years.

	
9441.4Nearly there...CLARID::KREYERAndre KREYER, Sophia Antipolis (FR)Tue Apr 15 1997 12:3129
>As it happens, one of the other fields in the device structure
>is one called "unit", which is described as the "physical unit
>number".  It is possible that this number is an encoding of
>the SCSI Bus, target and logical unit numbers for the device.
	On the system I use for test purposes, this was the case. Can
	I therefor assume that this is always true? Your wording left
	some doubts in my mind...

>Given that information it is possible to work out the device
>name as before if you can figure out what the general device
>type is; disk, tape, etc.  I think the string at the end of
>"dev_type" is this bit of information, but that string is in
>kernel space and you need to read from kernel memory to get
>it.
	Someone cares to expand on how to read from kernel memory? An
	example would be most helpful.

	At the moment, the code I wrote does assume that the device
	in question would be of type/prefix rz, rrz, re, rre, rmt or
	nrmt. Add to that the a-g LUN indicator if any, the unit number
	and the partition character and you get a name that I will look
	for in /dev: if found I use IOCTL to get the device name. Does
	this sound correct/complete?

	Your comments have been most helpful to get this thing going,
	thanks again for your time...

								.Andre.
9441.5NABETH::alanDr. File System&#039;s Home for Wayward Inodes.Tue Apr 15 1997 15:4623
	re: encoding of "unit" number.

	I would not be surprised if it changes in some future version.
	It may still be an encoding of the SCSI information, but the
	encoding may change.  Or it may change completely.  Since
	this sort of stuff is not defined by any standard, it can
	easily change.

	re: Reading from memory:

		if((fd = open("/dev/kmem", O_RDONLY)) == -1 )
			/* error handling */

		if( lseek(fd, kernel_address, SEEK_SET) == -1 )
			/* more error handling */

		if((rc = read(fd, buffer, size)) != rc )
			/* all sorts of error handling */

	Moving around in kernel memory is just like moving around
	within a file.  What you need to allow for is that some
	kernel addresses may not exist in a context that your
	process can use and you'll get errors.
9441.6Mapping table for address info in SteelSMURF::KNIGHTFred KnightWed Apr 16 1997 14:4146
What you are seeing is the first step towards the scsi-3
addressing space.  Since scsi-3 allows 2^64 targets and
2^64 luns, it becomes kind of hard to form a value out
of bus, target, and lun, and pack that into a single
unique devt (which is a 32 bit value).

Today we do something like:

(bus << 14) | (target << 10) | (lun << 6)

but that means 6 bits for bus, 4 bits for target and 4
bits for lun.  How on earth are we supposed to get a 64 bit
target number and a 64 bit lun number packed down into this
simple 32 bit devt.

I hope the answer is obvious - we CAN'T!

So, the number of the "cam" device is the index into an
internal mapping table.  Device cam0 is the first entry
in that table, cam1 is the second, cam5 the sixth, etc...

In that mapping table, are 3 64 bit values (one for the bus,
one for the target, and one for the lun).  So, you can now
have cam* devices at any arbitrary scsi address, with NO
formula to get you from the index to the address (you will
need to call a translation routine to ask for the physical
address, or physical addresses (plural)).

This will carry itself into the device name as well.  Again,
how do you put bus*8+target into a reasonable formula when
the target number is a full 64 bit value?  Again, you can't.
What about a full 64 bit lun value?  This doesn't work either.

So, /dev/disk/disk0a will be the "first" disk, /dev/disk/disk1c
will be the "second" disk, etc...  If disk0 has a devt for
cam3, then it will point to the 4th entry in the mapping table
to get it's bus, target, lun values.  There will no longer
be any static formula to get from btl to name, or from
devt to name, or name to devt, or name to btl, or anything
like that.

This is just a quick overview of some of the STEEL changes
that are coming as part of the requirement to support SCSI-3
and Fibre Channel.

	Fred