Question

est-il un moyen déterministe fiable, rapide, (à savoir pas une référence) pour vérifier si le lecteur système Mac OS X est un Solid State Drive?

Y at-il autre indicateur comment disque gère l'accès parallèle? Je suis en train de régler nombre de threads que mon programme va utiliser pour les opérations liées disque.

Je ne suis pas intéressé par la vitesse brute ou temps de recherche, seul quel type d'accès - est plus rapide pour le lecteur - série ou en parallèle. Je ne pense pas que les utilisateurs de mon programme à utiliser iSCSI ou RAID. SSD est mon objectif, tout le reste est agréable à avoir.

Device Characteristics de IOAHCIBlockStorageDevice contient ces informations. Comment puis-je lire par programmation?


Jusqu'à présent, j'ai compris il va comme ceci: (ci-après pseudocode)

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

Edit: Voici le code source complet . Je l'ai vérifié qu'il fonctionne avec Intel SSD et OCZ Vertex.

Était-ce utile?

La solution

Si vous essayez d'obtenir ce genre d'information, vous êtes la meilleure estimation est IOKit.

Vous pouvez essayer certaines d'entre elles fonctionnalité est en utilisant la ioreg outil de ligne de commande ou IORegistryExplorer .


Voici un code qui pourrait vous aider. Il va chercher tous les disques durs qui ne sont pas un RAID et ne sont pas des partitions. Ce n'est pas ce que vous voulez, mais il peut vous aider à démarrer.

#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

Autres conseils

En fait, je pense que vous devriez suivre la voie d'analyse comparative, car plus répond avec précision à votre question - vous ne pas vraiment soins que le disque se trouve être un SSD, vous venez de soins que le disque est vraiment rapide. Que faire si l'utilisateur utilise une configuration RAID rapide, ou un réseau Fibre Channel ou iSCSI utilise?

Il suffit de lire un tas de secteurs aléatoires du sous-jacent / dev / DiskX et si elle répond à vos besoins, vous pouvez le traiter comme un lecteur « rapide »

Cela ne semble possible pour les lecteurs internes. Je ne pouvais pas trouver un moyen à l'aide IOKit pour interroger un USB externe T5 Samsung 3 SSD pour son SSD-ness (ni Toshiba Canvio USB hddd). J'ai réussi pour le lecteur interne dans mon MBP, cependant.

Utilitaire de disque ne pense pas non plus le Samsung est un SSD, ce qui me fait penser il ne peut pas être un moyen, autre que pour mesurer la performance réelle.

Le nombre de threads? 1 va submerger un disque, SSD, RAID ou non. Disque est lent, le processeur est rapide. Le système d'exploitation va réorganiser vos demandes de disque de toute façon (ou du moins il devrait) pour obtenir les moindres mouvements de la tête.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top