Управление дисками и объемами
В дополнение к наблюдению за изменениями в объемах и отказе монтируют, размонтировали и извлекают вызовы, Дисковая Арбитражная платформа предоставляет возможность, чтобы получить различные данные об объеме, смонтировать и размонтировать объемы, и т.д. В этой главе описываются, как сделать это.
Получение дискового объекта
Прежде чем можно будет управлять диском или объемом, необходимо получить a DADiskRef
объект для того диска или объема. Можно получить a DADiskRef
объект четырьмя способами:
В качестве параметра переданный Вашему обратному вызову события (описанный в Использовании Дискового Арбитражного Уведомления и Обратных вызовов Утверждения)
От
io_service_t
ссылка пространства пользователя наIOMedia
объект для допустимой части устройства путем вызоваDADiskCreateFromIOMedia
Можно получить
io_service_t
ссылка пространства пользователя наIOMedia
объект путем вызоваIOServiceGetMatchingService
илиIOServiceGetMatchingServices
. Для приобретения знаний о работе с Реестром I/O считайте Основные принципы IOKit.От имени устройства BSD (
disk1s1
, например) использованиеDADiskCreateFromBSDName
От точки монтирования путем вызова
DADiskCreateFromVolumePath
Если у Вас есть любой io_service_t
возразите или имя устройства BSD, Ваше приложение может создать a DADiskRef
объект следующим образом:
Создайте a
DASessionRef
возразите, как описано в Создании Сеанса.Запланируйте его, как описано в Планировании Сеанса с Очередью Цикла или Отгрузки Выполнения. Убедитесь, что работает Ваша очередь отгрузки или выполни цикл.
Создайте дисковые объекты.
Управляйте ими, как желаемый.
Получение информации о диске
Дисковый арбитраж обеспечивает три функции для получения дополнительной информации о дисках и разделах: DADiskCopyDescription
, DADiskGetBSDName
, и DADiskCopyIOMedia
. Как правило можно получить почти любую информацию об определенном диске путем вызова DADiskCopyDescription
. Для некоторых довольно тайных данных, однако, Вам, вероятно, придется получить IOMedia
объект для диска и запроса тот объект.
Если Вам нужно имя устройства BSD диска или раздела (
disk1s1
, например) как струна до (обычно используемый при работе с уровнем POSIX APIs), вызватьDADiskGetBSDName
.Для большей части другой информации вызвать
DADiskCopyDescription
, как описано в Получении Словаря Описания.Если информация через, в которой Вы нуждаетесь не доступна
DADiskCopyDescription
, вызватьDADiskCopyIOMedia
.
Получение словаря описания
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); |
Извлечение диска
Извлечение диска подобно размонтированию объема. Существует два основных отличия:
Можно извлечь только целый раздел диска (
/dev/disk0
, например), не листовой раздел (/dev/disk0s3
, например). Если Вы запускаете с листового раздела, необходимо сначала получить целый раздел диска, содержащий его.Необходимо размонтировать все объемы на диске прежде, чем извлечь его. Чтобы гарантировать, что все объемы размонтированы (если возможный), сначала вызовите
DADiskUnmount
, передача целого раздела диска как дисковый параметр и установкаkDADiskUnmountOptionWhole
флаг в опциях размонтирования.
Для получения целого раздела диска, содержащего данный листовой раздел использовать 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 { |
... |
} |
} |