Is there any way of detecting if a drive is a SSD?

2020-01-27 02:51发布

I'm getting ready to release a tool that is only effective with regular hard drives, not SSD (solid state drive). In fact, it shouldn't be used with SSD's because it will result in a lot of read/writes with no real effectiveness.

Anyone knows of a way of detecting if a given drive is solid-state?

9条回答
唯我独甜
2楼-- · 2020-01-27 03:31

write text file
read text file

repeat 10000 times...

10000/elapsed

for an ssd will be much higher, python3:

def ssd_test():

    doc = 'ssd_test.txt'
    start = time.time()
    for i in range(10000):
        with open(doc, 'w+') as f:
            f.write('ssd test')
            f.close()
        with open(doc, 'r') as f:
            ret = f.read()
            f.close()
    stop = time.time()
    elapsed = stop - start
    ios = int(10000/elapsed)
    hd = 'HDD'
    if ios > 6000: # ssd>8000; hdd <4000
        hd = 'SSD'
    print('detecting hard drive type by read/write speed')
    print('ios', ios, 'hard drive type', hd)
    return hd
查看更多
【Aperson】
3楼-- · 2020-01-27 03:33

Finally a reliable solution! Two of them, actually!

Check /sys/block/sdX/queue/rotational, where sdX is the drive name. If it's 0, you're dealing with an SSD, and 1 means plain old HDD.

I can't put my finger on the Linux version where it was introduced, but it's present in Ubuntu's Linux 3.2 and in vanilla Linux 3.6 and not present in vanilla 2.6.38. Oracle also backported it to their Unbreakable Enterprise kernel 5.5, which is based on 2.6.32.

There's also an ioctl to check if the drive is rotational since Linux 3.3, introduced by this commit. Using sysfs is usually more convenient, though.

查看更多
男人必须洒脱
4楼-- · 2020-01-27 03:41

I wrote the following javascript code. I needed to determine if machine was ussing SSD drive and if it was boot drive. The solution uses MSFT_PhysicalDisk WMI interface.

function main()
{
    var retval= false;
    // MediaType - 0 Unknown, 3 HDD, 4 SSD
    // SpindleSpeed - -1 has rotational speed, 0 has no rotational speed (SSD)
    // DeviceID - 0 boot device
    var objWMIService = GetObject("winmgmts:\\\\.\\root\\Microsoft\\Windows\\Storage");
    var colItems = objWMIService.ExecQuery("select * from MSFT_PhysicalDisk");  
    var enumItems = new Enumerator(colItems);
    for (; !enumItems.atEnd(); enumItems.moveNext()) 
    {
        var objItem = enumItems.item();
        if (objItem.MediaType == 4 && objItem.SpindleSpeed == 0)
        {
            if (objItem.DeviceID ==0)
            {
                retval=true;
            }
        }
    }
    if (retval)
    {
        WScript.Echo("You have SSD Drive and it is your boot drive.");
    }
    else
    {
        WScript.Echo("You do not have SSD Drive");
    }
    return retval;
}
main();
查看更多
聊天终结者
5楼-- · 2020-01-27 03:42

You could get lucky by running

smartctl -i sda

from Smartmontools. Almost all SSDs has SSD in the Model field. No guarantee though.

查看更多
Ridiculous、
6楼-- · 2020-01-27 03:43

SSD devices emulate a hard disk device interface, so they can just be used like hard disks. This also means that there is no general way to detect what they are.

You probably could use some characteristics of the drive (latency, speed, size), though this won't be accurate for all drives. Another possibility may be to look at the S.M.A.R.T. data and see whether you can determine the type of disk through this (by model name, certain values), however unless you keep a database of all drives out there, this is not gonna be 100% accurate either.

查看更多
该账号已被封号
7楼-- · 2020-01-27 03:44

You can actually fairly easily determine the rotational latency -- I did this once as part of a university project. It is described in this report. You'll want to skip to page 7 where you see some nice graphs of the latency. It goes from about 9.3 ms to 1.1 ms -- a drop of 8.2 ms. That corresponds directly to 60 s / 8.2 ms = 7317 RPM.

It was done with simple C code -- here's the part that measures the between positions aand b in a scratch file. We did this with larger and larger b values until we have been wandered all the way around a cylinder:

/* Measure the difference in access time between a and b.  The result
 * is measured in nanoseconds. */
int measure_latency(off_t a, off_t b) {
  cycles_t ta, tb;

  overflow_disk_buffer();

  lseek(work_file, a, SEEK_SET);
  read(work_file, buf, KiB/2);

  ta = get_cycles();
  lseek(work_file, b, SEEK_SET);
  read(work_file, buf, KiB/2);
  tb = get_cycles();

  int diff = (tb - ta)/cycles_per_ns;
  fprintf(stderr, "%i KiB to %i KiB: %i nsec\n", a / KiB, b / KiB, diff);
  return diff;
}
查看更多
登录 后发表回答