有没有办法检测一个驱动器是否是SSD?
我正准备发布一个只对普通硬盘有效的工具,而不是SSD(固态硬盘)。 事实上,它不应该与SSD一起使用,因为它会导致大量的读写,而没有真正的效果。
任何人都知道检测一个给定的驱动器是否是固态的方法?
检测SSD并不像dseifert那样不可能。 linux的libata已经有了一些进步( http://linux.derkeiler.com/Mailing-Lists/Kernel/2009-04/msg03625.html ),尽pipe它看起来并没有用户准备好。
我完全明白为什么需要这样做。 这基本上是链接列表和数组之间的区别。 碎片整理等在SSD上通常会适得其反。
最后是可靠的解决scheme 其中两个,其实!
检查/ sys / block / sdX / queue / rotational,其中sdX是驱动器名称。 如果是0,则表示处理SSD,1表示普通旧硬盘。
我不能把自己的手指放在引入它的Linux版本上,但它存在于Ubuntu的Linux 3.2和vanilla Linux 3.6中,并不存在于2.6.38版本中。 Oracle也将其移植到基于2.6.32的Unbreakable Enterprise内核5.5。
还有一个ioctl来检查自Linux 3.3以来,驱动器是否轮转, 由此提交引入。 尽pipe使用sysfs通常更方便。
实际上,您可以很容易地确定旋转延迟 – 作为大学项目的一部分,我曾经这样做过。 这是在这个报告中描述。 你会想跳到第7页,在那看到一些很好的延迟图。 它从大约9.3毫秒到1.1毫秒 – 8.2毫秒的下降。 这直接对应于60 s / 8.2 ms = 7317 RPM
。
它是用简单的C代码完成的 – 这里是测量scratch文件中位置a
和b
之间的部分。 我们用更大和更大的b
值来做这件事,直到我们一直围绕着一个圆柱游走。
/ *测量a和b之间访问时间的差异。 结果 *以纳秒为单位进行测量。 * / int measure_latency(off_t a,off_t b){ 周期tt,tb; overflow_disk_buffer(); lseek(work_file,a,SEEK_SET); 读(work_file,buf,KiB / 2); ta = get_cycles(); lseek(work_file,b,SEEK_SET); 读(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); 返回差异; }
你可以运行幸运
smartctl -i sda
来自Smartmontools 。 几乎所有的SSD在型号领域都有SSD。 没有保证,但。
这个命令lsblk -d -o name,rota
列出你的驱动器,如果它是一个旋转磁盘,则在ROTA上有1,如果是SSD,则有0。 示例输出:
名字ROTA sda 1 sdb 0
SSD设备模拟硬盘设备接口,因此它们可以像硬盘一样使用。 这也意味着没有通用的方法来检测它们是什么。
您可能可以使用驱动器的某些特性(延迟,速度,大小),但这对于所有驱动器来说都不准确。 另一种可能是查看SMART数据,看是否可以通过这个(通过型号名称,某些值)来确定磁盘的types,但是除非你保存了所有驱动器的数据库,否则这不会是100%准确的。
我的两个美分来回答这个旧的,但非常重要的问题…如果一个磁盘通过SCSI访问,那么你将(可能)能够使用SCSI INQUIRY命令来请求其转速。 VPD(重要产品数据)页面被称为Block Device Characteristics
,其编号为0xB1
。 本页的第4和第5字节包含一个含义:
- 0000h“未报告中转速”
- “0001h”非旋转介质(例如,固态)“
- 0002h – 0400h“保留”
- 0401h-FFFEh“以每分钟转数(即,每分钟转数)为单位的标称介质转速(例如7200rpm = 1C20h,10000rpm = 2710h,15000rpm = 3A98h)
- FFFFh“保留”
所以SSD在这个领域必须有0001h
。 关于这个页面的T10.org
文档可以在这里find。
但是,这个标准的实施情况我不清楚。
我写了下面的JavaScript代码。 我需要确定机器是否正在使用SSD驱动器,以及它是否是启动驱动器。 该解决scheme使用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();