Управление дисками и объемами

В дополнение к наблюдению за изменениями в объемах и отказе монтируют, размонтировали и извлекают вызовы, Дисковая Арбитражная платформа предоставляет возможность, чтобы получить различные данные об объеме, смонтировать и размонтировать объемы, и т.д. В этой главе описываются, как сделать это.

Получение дискового объекта

Прежде чем можно будет управлять диском или объемом, необходимо получить a DADiskRef объект для того диска или объема. Можно получить a DADiskRef объект четырьмя способами:

Если у Вас есть любой io_service_t возразите или имя устройства BSD, Ваше приложение может создать a DADiskRef объект следующим образом:

  1. Создайте a DASessionRef возразите, как описано в Создании Сеанса.

  2. Запланируйте его, как описано в Планировании Сеанса с Очередью Цикла или Отгрузки Выполнения. Убедитесь, что работает Ваша очередь отгрузки или выполни цикл.

  3. Создайте дисковые объекты.

  4. Управляйте ими, как желаемый.

Получение информации о диске

Дисковый арбитраж обеспечивает три функции для получения дополнительной информации о дисках и разделах: DADiskCopyDescription, DADiskGetBSDName, и DADiskCopyIOMedia. Как правило можно получить почти любую информацию об определенном диске путем вызова DADiskCopyDescription. Для некоторых довольно тайных данных, однако, Вам, вероятно, придется получить IOMedia объект для диска и запроса тот объект.

Получение словаря описания

DADiskCopyDescription метод возвращает a CFDictionaryRef объект, содержащий несколько дюжин данных о диске или разделе. Некоторые обычно используемые данные включают:

  • Точка монтирования и имя тома

  • Имя узла устройства BSD и главные и незначительные числа

  • Информация об аппаратных средствах (устройство ID, идентификатор поставщика, GUID, и т.д.)

  • Информация соединения (соединяют шиной имя и путь),

Можно найти полный список свойств в DADisk.h заголовок в Дисковой Арбитражной Платформе, вместе с описанием ожидаемых типов данных для значений каждого ключа.

Например, для печати пути точки монтирования для объема:

DADiskRef disk;
CFDictionaryRef *diskinfo;
 
...
 
diskinfo = DADiskCopyDescription(disk);
CFURLRef fspath = CFDictionaryGetValue(dict,
                kDADiskDescriptionVolumePathKey);
 
char buf[MAXPATHLEN];
if (CFURLGetFileSystemRepresentation(fspath, false, (UInt8 *)buf, sizeof(buf))) {
    printf("Disk %s mounted at %s\n",
        DADiskGetBSDName(disk),
        buf);
 
    /* Print the complete dictionary for debugging. */
    CFShow(diskinfo);
} else {
    /* Something is *really* wrong. */
}

Для полного списка ключей словаря посмотрите раздел Constants в Ссылке DADisk.h.

Получение дополнительной информации от набора I/O

В некоторых редких ситуациях Вы, возможно, должны получить дополнительную информацию о диске вне того, что доступно от Дискового Арбитража. Если Вы делаете, можно вызвать DADiskCopyIOMedia получить io_service_t объект, который является представлением пространства пользователя IOMedia объект. Можно управлять этим объектом так же, как Вы были бы любой объект Реестра I/O.

Например, можно получить Базовый словарь Основы со свойствами I/O Registry носителей путем вызова IORegistryEntryCreateCFProperties на полученном объекте.

Свойства в словаре Реестра I/O определяются в Платформе Набора I/O. Для получения дополнительной информации посмотрите Ссылку Платформы Набора I/O.

Монтирование и размонтирование объемов

Чтобы смонтировать или размонтировать объем, вызвать DADiskMount или DADiskUnmount. Если Вы заботитесь, были ли монтирование или размонтирование успешны, необходимо также обеспечить обратный вызов для обработки результата.

Также можно вызвать DADiskMountWithArguments если необходимо передать дополнительные опции mount команда. Эта команда берет завершенный нулем массив CFStringRef значения, каждое из которых становится параметром mount команда. Можно найти наиболее распространенные опции в странице руководства для mount. Для дополнительных параметров формата объема см. страницу руководства для определенных команд монтирования, такой как mount_hfs.

Для каждой из этих функций функция обратного вызова берет три параметра: a DADiskRef объект, a DADissenterRef объект и указатель контекста (передал в качестве параметра, когда Вы регистрируете обратный вызов). Если работа была успешна, объект инакомыслящего NULL. Иначе, это предоставляет информацию о том, почему работа перестала работать.

Например, следующий отрывок размонтировал объем:

void unmount_done(DADiskRef disk,
    DADissenterRef dissenter,
    void *context);
 
...
 
DADiskUnmount(disk, kDADiskUnmountOptionDefault,
    unmount_done, NULL);
 
...
 
void unmount_done(DADiskRef disk,
    DADissenterRef dissenter,
    void *context)
{
    if (dissenter) {
        /* Unmount failed. */
        char buf[MAXPATHLEN];
        if (CFURLGetFileSystemRepresentation(fspath, false, (UInt8 *)buf, sizeof(buf))) {
            fprintf(stderr, "Unmount failed (Error: 0x%x Reason: %s).  Retrying.\n",
                DADissenterGetStatus(dissenter),
                buf);
        } else {
            /* Something is *really* wrong. */
        }
    } else {
        /* Do something. */
    }
}

Наиболее распространенные значения кода ошибки (ошибки, определенные для дискового арбитража), описаны в DAReturn перечисление. Однако эта функция может также потенциально возвратить любой другой код ошибки в mach_error_t пространство (ошибки UNIX, и т.д.).

Монтирование объема подобно за исключением того, что можно указать a CFURLRef объект с путем точки монтирования (или передача NULL смонтировать объем в стандартном расположении). Например:

unsigned char *mppath = "/mnt/mydisk";
 
path = CFURLCreateFromFileSystemRepresentation(
    kCFAllocatorDefault,
    mppath,
    strlen(mppath),
    true);
 
DADiskMountWithArguments(disk, path, kDADiskMountOptionDefault,
    mount_complete_callback, NULL,
    NULL);

Извлечение диска

Извлечение диска подобно размонтированию объема. Существует два основных отличия:

Для получения целого раздела диска, содержащего данный листовой раздел использовать DADiskCopyWholeDisk. Например:

DADiskRef wholedisk = DADiskCopyWholeDisk(disk);

Следующий отрывок, данный a DADiskRef объект связался с единственным разделом (вызванный partition), размонтировал все объемы на базовом диске, затем извлекает диск:

void unmount_done(DADiskRef disk,
    DADissenterRef dissenter,
    void *context);
void eject_done(DADiskRef disk,
    DADissenterRef dissenter,
    void *context);
 
...
 
/* Unmount all volumes */
DADiskRef wholedisk = DADiskCopyWholeDisk(partition);
DADiskUnmount(wholedisk, kDADiskUnmountOptionWhole,
    unmount_done, NULL);
CFRelease(wholedisk);
 
...
 
/* In the unmount callback, eject the volume. */
void unmount_done(DADiskRef disk,
    DADissenterRef dissenter,
    void *context)
{
    if (dissenter) {
        ...
    } else {
        DADiskEject(disk, kDADiskEjectOptionDefault,
            eject_done, NULL);
    }
}
 
/* Eject callback. */
void eject_done(DADiskRef disk,
    DADissenterRef dissenter,
    void *context)
{
    if (dissenter) {
        ...
    } else {
        ...
    }
}