【问题标题】:Is there any way of detecting if a drive is a SSD?有什么方法可以检测驱动器是否为 SSD?
【发布时间】:2010-10-28 20:02:47
【问题描述】:

我正准备发布一个只对普通硬盘有效的工具,而不是 SSD(固态硬盘)。事实上,它不应该与 SSD 一起使用,因为它会导致大量读取/写入而没有真正的效果。

有人知道检测给定驱动器是否为固态的方法吗?

【问题讨论】:

标签: disk hard-drive solid-state-drive


【解决方案1】:

终于找到了一个可靠的解决方案!实际上是两个!

检查 /sys/block/sdX/queue/rotational,其中 sdX 是驱动器名称。如果为 0,则表示您正在处理 SSD,而 1 表示普通的旧 HDD。

我无法确定引入它的 Linux 版本,但它存在于 Ubuntu 的 Linux 3.2 和 vanilla Linux 3.6 中,但不存在于 vanilla 2.6.38 中。 Oracle 还 backported 将其添加到基于 2.6.32 的 Unbreakable Enterprise 内核 5.5。

还有一个 ioctl 来检查驱动器是否从 Linux 3.3 开始旋转,由this commit 引入。不过,使用 sysfs 通常更方便。

【讨论】:

  • 这不包括混合驱动器。如果我通过这样的算法对混合驱动器进行碎片整理会怎样——它可能会缩短它的寿命吗?
【解决方案2】:

实际上,您可以很容易地确定旋转延迟——我曾经在大学项目中做过一次。它在this report 中有描述。您会想跳到第 7 页,在那里您会看到一些漂亮的延迟图表。它从大约 9.3 毫秒变为 1.1 毫秒——下降了 8.2 毫秒。这直接对应于60 s / 8.2 ms = 7317 RPM

已完成with simple C code - 这是测量临时文件中ab 位置之间的部分。我们使用越来越大的b 值进行此操作,直到我们一直绕着圆柱体游荡:

/* 测量 a 和 b 之间访问时间的差异。结果 * 以纳秒为单位。 */ int measure_latency(off_t a, off_t b) { 周期_t ta,tb; 溢出磁盘缓冲区(); lseek(work_file, a, SEEK_SET); 读取(工作文件,buf,KiB/2); ta = get_cycles(); lseek(work_file, b, SEEK_SET); 读取(工作文件,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); 返回差异; }

【讨论】:

  • 不是 C 代码!杰夫永远无法处理! PS:在播客中提到这一点,我们就可以喝酒了!
  • 呵呵 :-) 我刚看到“delphi”标签...对此感到抱歉 :-) 我相信你们会将其转换为 Pascal,我已经很多年没有使用过 Delphi。
【解决方案3】:

此命令lsblk -d -o name,rota 列出您的驱动器,如果是旋转磁盘,则 ROTA 为 1,如果是 SSD,则为 0。 示例输出:

名称罗塔 sda 1 数据库 0

【讨论】:

    【解决方案4】:

    检测 SSD 并不像 dseifert 所说的那样不可能。 linux 的 libata (http://linux.derkeiler.com/Mailing-Lists/Kernel/2009-04/msg03625.html) 已经有了一些进展,尽管它似乎还没有为用户准备好。

    我完全理解为什么需要这样做。这基本上是链表和数组之间的区别。碎片整理等通常在 SSD 上适得其反。

    【讨论】:

      【解决方案5】:

      你可以通过跑步获得幸运

      smartctl -i sda
      

      来自Smartmontools。几乎所有 SSD 在 Model 字段中都有 SSD。但不能保证。

      【讨论】:

      • 你的意思是smartctl -i /dev/sda
      【解决方案6】:

      我的两分钱来回答这个古老但非常重要的问题...如果通过 SCSI 访问磁盘,那么您将(可能)能够使用 SCSI INQUIRY 命令来请求其旋转速率。 VPD(重要产品数据)页面称为Block Device Characteristics,编号为0xB1。本页的第 4 和 5 字节包含一个有意义的数字:

      • 0000h "未报告中等旋转速率"
      • 0001h “非旋转介质(例如固态)”
      • 0002h - 0400h “保留”
      • 0401h - FFFEh “以每分钟转数为单位的标称介质转速(即, rpm)(例如,7 200 rpm = 1C20h、10 000 rpm = 2710h 和 15 000 rpm = 3A98h)"
      • FFFFh“保留”

      所以,SSD 在这个字段中必须有0001h。关于本页的T10.org文档可以在here找到。

      但是,我不清楚该标准的实施情况。

      【讨论】:

        【解决方案7】:

        我编写了以下 javascript 代码。我需要确定机器是否正在使用 SSD 驱动器以及它是否是引导驱动器。该解决方案使用 MSFT_PhysicalDisk WMI 接口。

        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();
        

        【讨论】:

        • 这不是答案。
        • 实际上,WMI 访问 MSFT_PhysicalDisk 对于​​ Windows 是正确的。但是我想知道 JavaScript 引擎如何使用它(我无法想象这个 API 可用于浏览器)。
        • 另外,如果 MediaType==4 已经确定 SSD 类型,为什么还要检查 SpindleSpeed。
        【解决方案8】:

        SSD 设备模拟硬盘设备接口,因此它们可以像硬盘一样使用。这也意味着没有通用的方法来检测它们是什么。

        您可能可以使用驱动器的某些特性(延迟、速度、大小),但这并不适用于所有驱动器。另一种可能性可能是查看 S.M.A.R.T.数据并查看您是否可以通过此确定磁盘类型(通过型号名称,某些值),但是除非您保留所有驱动器的数据库,否则这也不会 100% 准确。

        【讨论】:

        • 我同意,我认为唯一的方法是弄清楚制造商如何为他们的 SSD 设备而不是 HDD 设备生成串行密钥。然后建立所有制造商及其 SSD 字符串模式的列表。我曾经不得不寻找一些设备序列号来确定它们是否适合我的需求(美国市场的 iPod、带有 Linux fw 的 Linksys 路由器)
        • 说序列号是唯一可行的方法是不对的。一些驱动器确实有用地将其 RPM 报告为 1 或 0 (linux.derkeiler.com/Mailing-Lists/Kernel/2009-04/msg02562.html)
        • 也许你是对的,但我不确定。 “某些驱动器”--> 有问题,必须是所有驱动器,不要猜测。
        【解决方案9】:

        写入文本文件
        读取文本文件

        重复 10000 次...

        10000/elapsed

        对于一个ssd会高很多,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
        

        【讨论】:

        • 听说过混合驱动器吗?
        • @Marcin Orlowski 在通过写入速度搜索混合驱动器的情况下,定量方法是将更大的(20GB)json'ified numpy 数组写入磁盘,而不仅仅是“ssd 测试”;并从那里进行基准测试,因为混合动力车的固态硬盘容量很小。也许执行小文件和大文件的测试,然后您将能够辨别 hdd、hybrid 和 ssd。对于我的工作,反复读/写 IPC 的小文本文件,混合就可以了;它将为此目的充当ssd。操作人员特别要求需要硬盘......在这种情况下,ios&lt;1000 几乎可以确保这样。
        • 我的观点是,基于读/写速度的整个测试从头开始就有缺陷。通过检查速度,您无法权威地判断那是什么类型的介质 - 您只能确定它的快/慢。而已。你可以猜测,有时甚至会得到看起来有意义的结果,但我不会在此基础上构建任何东西。
        • 还有一个大问题叫cache
        猜你喜欢
        • 2013-01-18
        • 1970-01-01
        • 2016-12-01
        • 1970-01-01
        • 2010-09-30
        • 2015-04-28
        • 2010-11-04
        • 1970-01-01
        相关资源
        最近更新 更多