Каталог | Индекс раздела |
Назад | Оглавление | Вперед |
Ресурсы ввода/вывода не являются частью ядра. Обслуживающие программы ввода/вывода запускаются динамически при работе системы. Поскольку файловая система QNX является необязательным элементом, то пространство составных имен не является, как в большинстве монолитных операционных систем, частью файловой системы.
В системе QNX пространство составных имен разделено на области полномочий. Любой процесс, выполняющий файл-ориетированное обслуживание ввода/вывода, регистрирует у Администратора процессов свой префикс, определяя часть пространства имен, с которым он собирается работать (т.е. область своих полномочий). Эти префиксы образуют дерево префиксов, которое хранится в памяти каждого компьютера, загруженного системой QNX.
При открытии файла, его составное имя сопоставляется с деревом префиксов для того, чтобы направить запрос open() к соответствующему администратору ресурсов ввода/вывода. Например, Администратор устройств (Dev) обычно регистрирует префикс /dev. Если процесс вызывает функцию open(), задавая /dev/xxx, то в результате совпадения начала составного имени с префиксом /dev, запрос open() будет направлен к администратору Dev (владельцу). Дерево префиксов может содержать частично перекрывающиеся области полномочий. В этом случае выбор осуществляется по принципу наибольшего совпадения. Например, предположим, что имеется три зарегистрированных префикса:
4.1.1. Префиксы и области полномочий
4.2. Составные имена
4.2.1. Префиксы Администратора ввода/вывода
/ | файловая система на диске (Fsys); |
/dev | система символьных устройств (Dev); |
/dev/hd0 | дисковый том (Fsys). |
Администратор файловой системы зарегистрировал два префикса - один для смонтированной файловой системы QNX (/), а один для блок-ориентированного специального файла, который представляет целиком физический жесткий диск (/dev/hd0). Администратор устройств зарегистрировал один префикс.
Ниже в таблице приведен пример определения соответствующего администратора по принципу наибольшего совпадения.
Составные имена | Совпадает | Передается к |
/dev/con1 | /dev | Dev |
/dev/hd0 | /dev/hd0 | Fsys |
/usr/dtdodge/test | / | Fsys |
Дерево префиксов представляет собой список префиксов, разделенных двоеточиями, как показано ниже
prefix=pid,unit:prefix=pid,unit:prefix=pid,unit
pid | - это идентификатор процесса для администратора ресурсов ввода/вывода; |
unit | - это однознаковый номер, позволяющий выбирать один из нескольких возможных префиксов, которые имеет администратор. |
В предыдущем примере, если Fsys - это процесс 3, а Dev - процесс 5, то дерево системных префиксов могло бы выглядеть так
/dev/hd0=3, a:/dev=5, а:/=3,е
Если вам нужно | Воспользуйтесь |
Отобразить на экране дерево префиксов | Утилитой prefix |
Получить доступ к дереву префиксов из Си-программы | Функцией qnx_prefix_query() |
В системе QNX имеется понятие суперкорня или сетевого корня, использование которого позволяет задавать составные имена, минуя дерево префиксов конкретного узла. Сетевой корень задается двумя слешами, за которыми следует номер узла. Используя сетевой корень, можно легко получить доступ к файлам и устройствам, которые не входят в пространство составных имен вашего узла. Например, в типичной сети QNX следующие пути определяют:
/dev/ser1 | - последовательный порт своего узла; |
//10/dev/ser1 | - последовательный порт узла 10; |
//0/dev/ser1 | - последовательный порт своего узла; |
//20/usr/dtdodge/test | - файл на узле 20. |
Если вы хотите | Используйте |
Получить ваш текущий сетевой корень, используемый по умолчанию | Си функцию qnx_prefix_getroot() |
Установить ваш сетевой корень, используемый по умолчанию | Си функцию qnx_prefix_setroot() |
Запустить программу с новым сетевым корнем, используемым по умолчанию | утилиту on |
Процессы, даже выполняющиеся на одном узле, могут иметь разные сетевые корни, используемые по умолчанию. Например, один из процессов мог унаследовать сетевой корень, используемый по умолчанию, от породившего его процесса, который находился на другом узле сети, либо сетевой корень, используемый по умолчанию, мог быть явно изменен породившим процессом.
При передаче составных имен от одного процесса к другому, имеющему другой сетевой корень (например, при передаче файла системе буферизованной печати Spooler), необходимо определить сетевой корень до того, как составное имя будет передано процессу-получателю. Это можно не делать только в том случае, если вы уверены, что процесс-отправитель и процесс-получатель имеют один и тот же сетевой корень, используемый по умолчанию (либо если составное имя уже имеет лидирующие символы "//node/").
Мы рассмотрели префиксы с точки зрения установления их соответствия администраторам ресурсов ввода/вывода. Существует другая форма префиксов, так называемые альтернативные префиксы, которые обеспечивают простую строковую замену заданного префикса. Альтернативный префикс задается следующим образом
Например, предположим, что вы работаете на машине, которая не имеет своей файловой системы (поэтому нет процесса, работающего с префиксом "/"). Однако, существует файловая система на другом узле (скажем, на 10), с которой вы хотите работать, используя "/". Вы можете выполнить это, используя следующий альтернативный префикс
В этом случае ведущий символ (/) будет заменяться префиксом //10/. Например, имя
Это новое имя будет сопоставляться с деревом префиксов узла 10, т.к. оно начинается с символов "//10". В результате запрос open() будет направлен Администратору файловой системы узла 10. Таким образом, альтернативное имя позволит обеспечить доступ к удаленной файловой системе, как к своей собственной.
Нет необходимости запускать процесс локальной файловой системы для выполнения переадресации. Дерево префиксов на рабочей станции, не имеющей своего диска, может выглядеть следующим образом
В этом случае имена, начинающиеся с "/dev", будут адресованы своему Администратору устройств, а запросы с другими именами - к администраторам удаленной файловой системы.
Можно также использовать альтернативные префиксы для создания специальных имен устройств. Например, если Spooler печати работает на узле 20, то можно изменить имя своего принтера на альтернативное следующим образом
Любой запрос на открытие /dev/printer будет перенаправлен по сети к реальному Spooler печати. Аналогично, если у вас нет своего накопителя на гибких магнитных дисках, то вы можете обратиться к дисководу на узле 20, используя следующий альтернативный префикс
В обоих рассмотренных выше случаях альтернативную переадресацию можно не выполнять, а к удаленному ресурсу обращаться непосредственно
Совершенно не обязательно начинать имена с одного или двух слэшей. В этом случае путь считается относительным к текущему рабочему каталогу. QNX хранит текущий рабочий каталог в виде символьной строки. Относительные составные имена всегда преобразуются в полные сетевые имена посредством добавления строки, содержащей имя текущего рабочего каталога, к относительному имени.
4.2.4. Альтернативные префиксы
префикс = строка-замена
/=//10/
/usr/dtdodge/test
будет заменено на
//10/usr/dtdodge/test.
/dev = 5,а:/=//10/
Создание специальных имен устройств
/dev/printer=//20/dev/spool
/dev/fd0=//20/dev/fd0
//20/dev/spool или //20/dev/fd0
4.2.5. Относительные составные имена
Для того, чтобы получить полное сетевое имя, вы можете воспользоваться утилитой fullpath. |
При открытии какого-либо ресурса ввода/вывода, происходит обращение к различным пространствам имен. Функция open() возвращает целочисленное значение, которое называется дескриптором файла (FD), в дальнейшем используемое для направления запросов на ввод/вывод к соответствующему администратору. (Отметим, что функция Sendfd(), обращающаяся к ядру, вызываемая из библиотеки подпрограмм, используется для направления запроса.)
Пространство имен дескрипторов файлов, в отличие от пространства составных имен, исключительно локально для каждого процесса. Для идентификации управляющей структуры, связанной с предыдущим вызовом функции open(), администратор использует комбинацию PID (идентификатор процесса) и FD (дескриптор файла). Эта структура называется управляющим блоком открытия (open control block - OCB) и содержится в администраторе ввода/вывода.
На рис._16 показано, как администратор ввода/вывода устанавливает соответствие между отдельными парами PID, FD и OCB.
![]() |
Рис. 16 |
Управляющий блок открытия (OCB) содержит текущую информацию об открываемом ресурсе. Например, файловая система сохраняет текущий указатель поиска в файле. Каждая функция open() создает новый ОСВ. Поэтому, если процесс открывает один и тот же файл дважды, то любые вызовы lseek(), использующие один FD, не будут влиять на указатель поиска для другого FD. То же самое происходит, когда разные процессы открывают один и тот же файл.
На рис. 17 схематически изображены два процесса, один из которых открывает два раза, а другой - один раз тот же самый файл. Для каждого процесса создаются свои дескрипторы файлов.
![]() |
Процесс A открывает файл /tmp/file два раза. Процесс B открывает тот же файл один раз.
Рис. 17 |
Несколько дескрипторов файлов одного или более процессов могут ссылаться на один и тот же ОСВ. Это достигается двумя способами:
Когда несколько дескрипторов файлов ссылаются на один и тот же ОСВ, то любое изменение состояния ОСВ немедленно становится "видимым" всем процессам, имеющим дескрипторы файлов, связанные с данным ОСВ.
Например, если некоторый процесс использует функцию lseek() для изменения положения указателя поиска, то чтение или запись происходит с новой позиции указателя, и при этом совершенно не важно, какой дескриптор файла используется.
На рис. 18 показаны два процесса, один из которых открывает файл дважды, а затем с помощью функции dup() - третий раз. Затем процесс порождает другой процесс, который наследует все открытые файлы.
![]() |
Процесс дважды открывает файл, а затем получает еще один FD с помощью функции dup(). Порожденный процесс наследует все три дескриптора.
Рис. 18 |
Можно запретить наследование дескрипторов файлов процессами, создаваемыми функциями spawn() или exec(), с помощью функции fcntl(), установив флаг FD_CLOEXEC.
Назад | Оглавление | Вперед |
Каталог | Индекс раздела |