Pregunta

¿Hay una manera fiable, rápido, determinista (es decir, no un punto de referencia) para comprobar si la unidad del sistema Mac OS X está en una unidad de estado sólido?

¿Hay algún otro indicador de lo bien que maneja el acceso de disco paralelo? Estoy tratando de ajustar el número de hilos que mi programa se va a utilizar para las operaciones de discos de ruedas.

No estoy interesado en la velocidad pura o el tiempo de búsqueda, sólo qué tipo de acceso - serie o paralelo - es más rápido para la unidad. No espero que los usuarios de mi programa para utilizar iSCSI o RAID. SSD es mi enfoque, todo lo demás es agradable a tener.

Device Characteristics de IOAHCIBlockStorageDevice contiene esta información. ¿Cómo puedo leer mediante programación?


Hasta ahora he descubierto que es la siguiente: (siguiente es pseudocódigo)

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

Editar: Aquí está el código fuente completo . He verificado que funciona con Intel SSD OCZ Vertex y.

¿Fue útil?

Solución

Si usted está tratando de obtener ese tipo de información, que eres el mejor conjetura es IOKit.

Puede probar algunos de su funcionalidad mediante el ioreg herramienta de línea de comandos o el IORegistryExplorer .


Aquí hay un código que podría ayudarle. Se obtiene todos los discos duros que no son RAID y no son particiones. Esto no es lo que quiere, pero podría ayudarle a empezar.

#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

Otros consejos

En realidad, creo que debería ir a la ruta de evaluación comparativa, porque responde con mayor precisión su pregunta - No realmente cuidado de que el disco pasa a ser un SSD, que sólo se preocupan de que el disco es muy rápido. ¿Qué pasa si el usuario está utilizando una configuración RAID rápido, o una matriz de canal de fibra o iSCSI está utilizando?

Basta con leer un montón de sectores aleatorios del subyacente / dev / diskX y si cumple con sus requisitos se puede tratar como una unidad de "rápido"

Esto sólo parece posible que las unidades internas. No pude encontrar una manera de utilizar IOKit para consultar un USB externo 3 SSD Samsung T5 para su SSD-dad (ni HDDD USB Toshiba Canvio). Me las arreglé para la unidad interna en mi MBP, sin embargo.

utilidad

disco también no cree que el Samsung es un SSD, por lo que me hace pensar que no puede haber una manera, que no sea para medir el rendimiento real.

El número de hilos? 1 va a abrumar a cualquier disco, SSD, RAID o no. El disco es lento, un procesador rápido. El sistema operativo va a reordenar sus solicitudes de disco de todos modos (o al menos debería) para obtener los movimientos mínimos de cabeza.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top