2010-01-17 73 views
7

有没有一种可靠,快速,确定性的方法(即不是基准)来检查系统驱动器Mac OS X是否打开是固态硬盘?如何在Mac OS X中检测SSD?

是否有任何其他指标磁盘如何处理并行访问?我试图调整我的程序将用于磁盘绑定操作的线程数。

我对原始速度或寻道时间不感兴趣,只有哪种类型的访问 - 串行或并行 - 对于驱动器来说更快。我不希望我的程序的用户使用iSCSI或RAID。固态硬盘是我的重点,其他任何东西都很好。

Device CharacteristicsIOAHCIBlockStorageDevice包含此信息。我如何以编程方式阅读它?


到目前为止,我已经想通了,它是这样的:(以下是伪代码)

match = IOBSDNameMatching(kIOMasterPortDefault,0,"disk0s2"); 
IOServiceGetMatchingServices(kIOMasterPortDefault, match, &iterator); 
while(entry = IOIteratorNext(iterator)) { 
    do { 
    entry = IORegistryEntryGetParentEntry(nextMedia, kIOServicePlane, &entry); 
    dict = IORegistryEntryCreateCFProperty(nextMedia, 
      CFSTR(kIOPropertyDeviceCharacteristicsKey), kCFAllocatorDefault, 0); 
    [dict objectForKey:CFSTR(kIOPropertyMediumTypeKey)]; 
    } 
    while(!dict && entry); 
} 

编辑:Here's complete source code。我已经验证它适用于英特尔SSD和OCZ Vertex。

+0

也http://stackoverflow.com/q/908188/545127 – Raedwald 2013-03-04 14:32:30

回答

5

如果你想获得这种信息,你最好猜测是IOKit。

你可以尝试一些它的使用名为ioreg命令行工具或IORegistryExplorer功能。


下面是一些代码,可以帮助你。它读取所有不是RAID的硬盘,也不是分区。这不是你想要的,但它可能会让你开始。

#import "TWDevice.h" 

#include <stdio.h> 
#include <string.h> 
#include <unistd.h> 
#include <fcntl.h> 
#include <sys/ioctl.h> 
#include <errno.h> 
#include <paths.h> 
#include <sys/param.h> 
#include <IOKit/IOKitLib.h> 
#include <IOKit/IOBSD.h> 
#include <IOKit/storage/IOMedia.h> 
#include <CoreFoundation/CoreFoundation.h> 
#include <IOKit/Kext/KextManager.h> 


@implementation TWDevice 

@synthesize name, devicePath, size, blockSize, writable, icon; 

+ (NSArray *)allDevices { 
    // create matching dictionary 
    CFMutableDictionaryRef classesToMatch; 
    classesToMatch = IOServiceMatching(kIOMediaClass); 
    if (classesToMatch == NULL) { 
     [NSException raise:@"TWError" format:@"Classes to match could not be created"]; 
    } 

    // get iterator of matching services 
    io_iterator_t mediaIterator; 
    kern_return_t kernResult; 
    kernResult = IOServiceGetMatchingServices(kIOMasterPortDefault, 
                     classesToMatch, 
                     &mediaIterator); 

    if (kernResult != KERN_SUCCESS) { 
     [NSException raise:@"TWError" format:@"Matching services did not succed."]; 
    } 

    // iterate over all found medias 
    io_object_t nextMedia; 
    NSMutableArray *detectedDevices = [NSMutableArray array]; 
    while (nextMedia = IOIteratorNext(mediaIterator)) { 
     NSMutableDictionary *properties; 
     kernResult = IORegistryEntryCreateCFProperties(nextMedia, 
                        (CFMutableDictionaryRef *)&properties, 
                        kCFAllocatorDefault, 0); 

     if (kernResult != KERN_SUCCESS) { 
      [NSException raise:@"TWError" format:@"Getting properties threw error."]; 
     } 

     // is it a whole device or just a partition? 
     if ([[properties valueForKey:@"Whole"] boolValue] && 
      ![[properties valueForKey:@"RAID"] boolValue]) { 
      TWDevice *device = [[[TWDevice alloc] init] autorelease]; 

      device.devicePath = [NSString stringWithFormat:@"%sr%@", _PATH_DEV, [properties valueForKey:@"BSD Name"]]; 
      device.blockSize = [[properties valueForKey:@"Preferred Block Size"] unsignedLongLongValue]; 
      device.writable = [[properties valueForKey:@"Writable"] boolValue]; 
      device.size = [[properties valueForKey:@"Size"] unsignedLongLongValue]; 

      io_name_t name; 
      IORegistryEntryGetName(nextMedia, name); 
      device.name = [NSString stringWithCString:name encoding:NSASCIIStringEncoding]; 

      … 

      [detectedDevices addObject:device]; 
     } 

     // tidy up 
     IOObjectRelease(nextMedia); 
     CFRelease(properties); 
    } 
    IOObjectRelease(mediaIterator); 

    return detectedDevices; 
} 

@end 
+0

@porneL:我已经添加了一些代码,可能会对您有所帮助。 – 2010-01-17 20:02:53

+0

谢谢。这非常有帮助。没有它,我会毫无用处地戳IOKit C++ API。 – Kornel 2010-01-17 21:14:03

+0

@porneL:它看起来像你自己想出来的。我想你在这个问题上不需要任何帮助,对吗? – 2010-01-18 06:47:25

6

其实,我觉得你应该去的基准路线,因为它更准确地回答你的问题 - 你不真的护理磁盘恰好是一个SSD,你只关心这个盘是真快。如果用户使用快速RAID设置或光纤通道阵列或使用iSCSI,会怎么样?

刚刚从底层的/ dev/diskX读了一堆随机扇区的,如果它符合您的要求,你可以把它当作一个“快”驱动

+2

见我没有“快”的任何基线测量。我将不得不运行两个基准并进行比较。花费在可靠基准上的时间可能比通过选择更好的策略节省时间更长。短基准将变得不可靠,并且考虑到缓存,延迟等是非常棘手的。 我在寻找快速,确定性的解决方案。除了SSD之外,不需要任何支持。 – Kornel 2010-01-17 18:59:26

+1

不够公平,但我会告诉你的是,这是Windows操作系统采用的方法 - 如果你看到一些统计信息,它将很容易看到;运行2个测试,其中一个具有向后顺序读取(即扇区5,4,3,2等),然后读取具有随机扇区的第二个测试。如果差异基本相同,那么您就有SSD;在机械磁盘上​​它们会有很大的不同 – 2010-01-17 20:13:52

0

线程的数量? 1将压倒任何磁盘,SSD,RAID或不。磁盘速度慢,处理器速度很快。无论如何(或者至少应该),操作系统会重新排序磁盘请求以获得最少的磁头移动。

+0

至少在Windows和Linux上,操作系统不会重新排序SSD的磁盘请求 – 2010-01-17 18:57:45

+1

根据我的经验,OS X在管理磁盘访问方面做得不好(并行访问会导致垃圾回收而不是效率更高访问)。访问SSD的多个I/O绑定线程速度更快 - 也许只是因为涉及一些CPU开销,但速度更快。 – Kornel 2010-01-18 11:48:08