How can I identify the protocol used in hard disk?
Asked Answered
A

4

7

I have an application which needs to read information from a hard disk, stuff like serial model etc.

Now of course it matters if the drive is a SAS, SATA or FC drive.

Is there a reliable way that I can identify which protocol a connected drive uses? Either via an OS command or checking some logs or inquiring the device?

I don't want to use sysfs structure. I want to know how the OS know if it's an ATA, SCSI or whatever type of disk.

Astrometry answered 7/8, 2014 at 14:41 Comment(17)
it'd probably be buried in /proc somewhere.Diastyle
Might be a duplicate of stackoverflow.com/questions/17213762/linux-rhel-find-disk-typeCaudad
these us either the sysfs file structure or external programs. I want to know how to 'ask the disk' or controller it is attached to.Astrometry
sysfs is not a file structure, it's the pseudo-filesystem the kernel uses to export the information. The contents are generated by the kernel when you try to read the pseudo-files, similar to entries in /proc. You explicitly state you don't want to use /sys, but that -- and possibly some bus- and/or controller-specific ioctls -- is the answer. You've painted yourself in a corner; good luck.Roofdeck
so what you are telling me is the magical kernel developers can do magical things we can`tAstrometry
Which systems do you want support? I can write code sample for you for Linux.Ofelia
linux, prefably i`d get a general pointer on how to do this so I can replicate to other systems if necessaryAstrometry
@RG337: No, I'm telling you the kernel exports most of the information you want via the /sys/ pseudo-filesystem. (In fact, you only need that, and in some cases some driver/bus/device-specific ioctls to get all the information; a handful of command-line tools can do that for you.) By rejecting /sys/, you are tying your own hands behind your back.Roofdeck
I am rejecting /sys/ because I want to work towards an OS independant solution. I don`t just want to know whether it is a SAS, SATA, SCSI, FC or whatever disk I want to know HOW it knows what disk it is and replicate it via talking to the device instead of asking the kernel.Astrometry
@RG337: Will not work, because this is very OS specific. The existing cross-platform utilities have OS-specific code, and only present an uniform interface. There just is no OS-independent solution. Furthermore, most OS kernels don't allow userspace to talk directly to the devices at the same level and detail as the kernel does, because it is dangerous if not perfectly coordinated: loss of data, deadlocks, etc. may occur. Perhaps you could read some of the sdparm background, to get a better overview?Roofdeck
@RG337 There are some specific limitations in Linux here, the main issue is that Linux disguises almost all types of disk as SCSI to userspace applications to allow for a uniform front end. You could make a solution for this using a kernel module, or you could use the sys filesystem. What I feel you may not understand is that there is no cross platform way to do this. Linux and every other good OS intentionally hides the hardware from userspace in order to present a hardware independent interface. If running bare metal code you could simply probe the PCI registers to find out ... continued...Aurita
@RG337 What kind of device it is, however an OS will not let you do this, most OSes provide a way for you to do this through the OS, via a filesystem such as sys or a utility but they each implement this method differently and there is no cross platform way. You are going to have to write as many solutions as OSes you wish to support or use a program such as hdparm to provide an abstraction layer for you. As I said before, if you wish to use kernel methods, write a kernel module to do it but be aware, it will only run for the kernel you write it for making it even less portable.Aurita
that is very unfortunate. I had hoped the drive or bus would report in some way what protocol it supports but it seems there is no way for me to tell if a connected disk is a SCSI or SATA or whatever diskAstrometry
I mean there is no global way to get model and serial information but saying that you need to send a SCSI inquiry or ATA IDENTIFY would be enough for me.Astrometry
@RG337: You're disappointed, because your chosen approach does not work, and you refuse to consider any others, just exclaim "it is impossible for me". The problem is your approach, not your target. I and others happily use the OS-specific interfaces (like /sys/block/DEVICE pseudosymlink and /sys/block/DEVICE/device/vendor and /block/DEVICE/device/model pseudofiles in Linux, and sdparm, hdparm, and smartctl cross-platform utilities on all architectures) to find this information with minimum fuss and high reliability. Why does that not work for you?Roofdeck
I can perfectly replicate sdparm, hdparm and smartctl on my own. This is of little significance and can be fully done using standardized knowledge on SCSI and ATA commands. The problem for me is the kernel has a way of exposing the command set a drive talks in. I want to know how it does that. I do not need a code snippet which works on a particular platform. I want to know HOW the kernel acquires this information from the disk/bus. an analogy is that of getting the serial information of a disk via /sys or via a SCSI inquiry. Is getting it via inquiry useless? of course not.Astrometry
@RG337: Your original question states you have an application running under an OS. Therefore, you must use the interfaces the OS exposes, which are not portable: you always need some architecture/OS-specific code. In Linux, that involves examining /sys/, but you rejected that. Because of that, I said you've made the task impossible for yourself. Now you say you want to know how the kernels do this. (That answer is easy, in the sources.) That will not help your application: kernel has access and privileges userspace does not. You've limited yourself to a sterile approach.Roofdeck
G
6

As you have mentioned in comments to user3588161's answer, you are having SATA and SAS disk attached to the same SAS controller, so I'd suggest to use the smartctl command!

The smartctl command act as a control and monitor Utility for SMART disks under Linux and Unix like operating systems. Type the following command to get information about /dev/sda (SATA disk):

# smartctl -d ata -a -i /dev/sda

For SAS disk use one of the following syntax:

# smartctl -d scsi --all /dev/sgX
# smartctl -d scsi --all /dev/sg1
# smartctl -d scsi --all /dev/sg1 -H

I guess all of the information is somehow related to this location :-

/sys/class/scsi_device/?:?:?:?/device/model

I suggest you try doing this too to check what output does it render.

cat /sys/class/scsi_device/0\:0\:0\:0/device/{model,vendor}

(The backslashes next to zeros are for escaping special char :.)

Also, I'd like to suggest you to visit these two links in order for more information or detail like sample output,etc :-

Find Out Hard Disk Specs

To Check Disk behind Adaptec RAID Controllers

Gilmagilman answered 10/8, 2014 at 3:29 Comment(0)
P
3

Answer rewritten in view of clarification: libATA is what you want. It's what hdparm calls and it reports the transport too. It's hard to find up to date docs on it though. See http://docs.huihoo.com/linux/kernel/2.6.26/libata/index.html for example.

I have not used libATA (directly) myself, so I can't be more specific as to the API calls needed. Since not many people need to write something like hdparm themselves, your best bet is to consult its sources to see what exactly it calls.

hdparm can report stuff like:

[root@alarmpi ~]# hdparm -I /dev/sdb

/dev/sdb:

ATA device, with non-removable media
   Model Number:       TOSHIBA DT01ACA200                      
   Serial Number:      Z36GKMKGS
   Firmware Revision:  MX4OABB0
   Transport:          Serial, ATA8-AST, SATA 1.0a, SATA II Extensions, SATA Rev 2.5, SATA Rev 2.6, SATA Rev 3.0; Revision: ATA8-AST T13 Project D1697 Revision 0b

If your actual problem is that only sdparm works on your system for SCSI drives (can happen) then it seems the problem is reduced to figuring out which of hdparm or sdparm to call isn't it? You could use udevinfo for that. See https://chromium.googlesource.com/chromiumos/third_party/laptop-mode-tools/+/775acea9e819bdee90cca8d2363827c13967a14b/laptop-mode-tools_1.52/usr/share/laptop-mode-tools/modules/hdparm for example.

Packard answered 10/8, 2014 at 2:34 Comment(7)
like stated in the question I don`t want to use external tools to do this. I want directly query the disk and/or controller. something like sending a specific command via sg driver or some other way.Astrometry
I misunderstood what you meant by "OS command". You should rewrite that as "system call".Hapte
well I would still be using system calls as ioctl() is a system call. lshw and other tools are applications usually included in a linux system but I would hardly call them a system callAstrometry
libata won`t work on scsi protocal based disk. You can test this yourself if you have a SCSI, SAS or FC disk handy. Try using hdparm on it.Astrometry
as a sidenote, currently I use a hack where I try to send a HDIO_GET_IDENTITY ioctl() and if it fails I will assume it is SCSI based disk.Astrometry
Actually it usually can. You are probably running a virtualizing controller. See serverfault.com/questions/499434/…Hapte
I can directly acces the disk. hdparm with libata fails doing this. My own utilities and sdparm can. This a known fault for hdparm and one of the reasons sdparm exists. I just tested to be sure. I have a SATA and SAS disk attached to the same SAS controller. hdparm is fine with the SATA disk but cries for the SAS diskAstrometry
G
3

Checking boot information, it seems the disk type is set in kernel ahci calls. You can check (as root) with dmesg | grep ahci (on sysvinit systems) or with journalctl -k -b -0 -l --no-pager | grep ahci (with systemd). The relevant query/setting looks to be:

kernel: ahci 0000:00:12.0: version 3.0
kernel: ahci 0000:00:12.0: controller can't do 64bit DMA, forcing 32bit
kernel: ahci 0000:00:12.0: AHCI 0001.0100 32 slots 4 ports 3 Gbps 0xf impl SATA mode
kernel: ahci 0000:00:12.0: flags: ncq sntf ilck pm led clo pmp pio slum part ccc

The third line holds the controller/type information you are looking for. This seems to be where the information comes from, but from your questions standpoint, it isn't a viable solution.

The question becomes where does this information get recorded or stored within /dev /proc or /sys. I have looked and cannot find a one-to-one correlation between this initial determination of disk type on boot and any flag stored. This information may well be part of the coded data, for example, /sys/class/scsi_disk/0:0:0:0/device or similar location. Hopefully this information may allow you or others to help pinpoint if, and if so, where this information is captured and available on a running system.

Godfather answered 10/8, 2014 at 3:22 Comment(2)
thanks for your help. it`s obvious this information is available on some way. the kernel developers code perform the magic that allows the kernel to know, unfortunately I have been searching for a couple of months with no luck though.Astrometry
This is a heck of a challenge. Obviously the kernel guys have a way of doing it. I suppose their code reads some sector and extracts some bitfied that holds this information. Good luck to you. This information may well be documented in some 25 year old IBM manual explaining what interrupt call is necessary that has since been supplemented with BIOS/kernel updates to support new drive types as they emerge.Godfather
D
0

I like to simply run:

smartctl --scan

this should list all connected devices, along with the protocol for each device (ATA or SCSI)

Dissolvent answered 20/6, 2024 at 22:19 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.