如何在Mac OS X中检测SSD?

时间:2010-01-17 17:41:27

标签: cocoa macos ssd iokit

是否有可靠,快速,确定的方式(即基准)来检查系统驱动器Mac OS X是否为固态硬盘?

是否还有其他指示器磁盘如何处理并行访问?我正在尝试调整我的程序将用于磁盘绑定操作的线程数。

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

Device Characteristics的{​​p> IOAHCIBlockStorageDevice包含此信息。我如何以编程方式阅读?


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

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。

4 个答案:

答案 0 :(得分:6)

实际上,我认为您应该采用基准测试路线,因为它更准确地回答了您的问题 - 您并非真的关心磁盘碰巧是SSD,您只关心磁盘真的很快如果用户使用快速RAID设置,光纤通道阵列或正在使用iSCSI,该怎么办?

只需从底层的/ dev / diskX中读取一堆随机扇区,如果符合您的要求,您可以将其视为“快速”驱动器

答案 1 :(得分: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

答案 2 :(得分:1)

这似乎仅适用于内部驱动器。我找不到使用IOKit来查询Samsung T5外部USB 3 SSD的SSD外观的方法(也没有查询东芝Canvio USB HDDD的方法)。不过,我确实在MBP中管理内部驱动器。

磁盘实用程序也不认为三星是SSD,因此让我认为除了衡量实际性能外,别无选择。

答案 3 :(得分:0)

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