А. Робачевский - Операционная система UNIX (1114671), страница 64
Текст из файла (страница 64)
Как уже обсуждалось, доступ к периферии в U N I X осуществля!ется с помощью специальных файлов устройств, расположенных в корне!вой файловой системе некоторого типа, например ufs. В соответствии сархитектурой виртуальной файловой системы, все операции с этими фай!лами будут обслуживаться соответствующими функциями реальной файло!вой системы, в данном случае — ufs.Однако такой схеме недостает традиционного для UNIX изящества. Спе!циальный файл устройства не является обычным файлом системы ufs.Фактически все операции со специальным файлом устройства выполняют!ся драйвером и не зависят от типа файловой системы.
Поэтому было былогичнее отобразить операции vnode не на вектор файловой системы, анепосредственно на коммутатор устройств.Современные системы ветви System V используют для этого специальныйтип файловой системы, называемый devfs илиДля этого типа фай!ловой системы все операции vnode адресуют соответствующие функциитребуемого элемента коммутатора устройств. После первоначального от!крытия файла, когда создается vnode, все запросы, связанные со специ!альным файлом устройства, проходят через vnode файловой системыspecfs.В то же время открытие файла, например с помощью системного вызовапредусматривает ряд операций, реализованных реальной файловойВ системах SVR4 принята терминология specfs, операционная система SCOкото!рая формально являетсяно фактически имеет многие чертыназывает этоттип файловой системы devfs.www.books-shop.com334Глава 5.системой, в которой находится специальный файл устройства (в нашемпримереОдной из таких операций является трансляция имени, кото!рая не может быть реализована файловой системой specfs, по существу яв!ляющейся виртуальной.Решение данной проблемы рассмотрим на конкретном примере.
Допус!тим, процесс вызывает функциюдля специального файла устрой!ствадля работы с виртуальной памятью ядра. Функция транс!ляции имени файловой системы ufs —сначала откроетфайлаа затем, прочитав каталог, обнаружитфайлапри этом будет размещенэтого файла. Однакоопре!делит, что тип этого файла IFCHR, т. е. специальный файл символьногоустройства.
Поэтому вместо функцииs_openбессмысленной дляэтого типа файла, будет вызвана специальная функция файловой системыspecfs, которая создаст собственный индексный дескриптор, описываемойструктурой(от special inode), для этого файла, если таковой уже ненаходится в памяти. Согласно стандартной процедуре, также будет создани виртуальный индексный дескриптор vnode, который будет указывать навектор операций specops, которые специально предназначены для работыс драйверами устройств. Например, функцииилив свою очередь вызовут соответствующие точки входадрайвера — функции,илиПосле этогофункцииs_openбудет передан адрес этого vnode, который она, всвою очередь, передаст системному вызовуВ результате, ореп(2)вернет процессу файловый дескриптор, адресующий vnode файловой сис!темы specfs, а не vnode файла /dev/kmem.
Таким образом, все дальнейшиеоперации с /dev/kmem будут перехватываться файловой системой specfs.Схема связи процесса с этим vnode приведена на рис. 5.4.Рис. 5.4. Связь процесса с файлом /dev/kmem после его открытияwww.books-shop.com335Однако изложенная схема является неполной и имеет ряд существенныхнедостатков. Дело в том, что драйвер конкретного устройства может адресо!ваться несколькими специальными файлами устройств, возможно, располо!женными в различных физических файловых системах. В этом случае ядробессильно определить фактическое число связей прикладных процессов сданным устройством, что может потребоваться, например, при вызовефункциикогда все процессы закончили работу с устройством.Для решения этой проблемы файловая система specfs предусматривает на!личие дополнительного snode, позволяющего контролировать доступ кконкретному устройству.
Этот объект, получивший название общего snode(common snode), является единственным интерфейсом доступа к драйверуустройства. Для каждого устройства (драйвера устройства) существуетединственный common snode, который создается при первом доступе кустройству. Каждый специальный файл устройства, в свою очередь, имеетсобственный snode в файловой системе specfs и соответствующий емуvnode, а также inode физической файловой системы, где расположен спе!циальный файл устройства, и соответствующий ему vnode.Для связи всех этих индексных дескрипторов между собой snode имеет дваполя:указывающее на common snode, и s_realvp, указы!вающее на vnode специального файла устройства файловой системы, гдерасположен последний.Использование тех или иных vnode и связанных с ними inode или snodeзависит от конкретных операций, выполняемых процессом с устройством.Большинство из этих операций не зависят от имени специального файлаустройства и, соответственно, от реальной файловой системы, в которойон расположен.
Эти операции выполняются через vnode, соответствующийcommon snode. Однако существует ряд операций, выполнение которых за!висит от конкретного специального файла устройства, через который про!цесс взаимодействует с драйвером. Примером может служить проверкаправ доступа при открытии специального файла устройства, которые рас!положены вреальной файловой системы. В этом случае ис!пользуется vnode соответствующего специального файла устройства.Схема описанной архитектуры приведена на рис. 5.5.КлоныКак уже обсуждалось, старший номер устройства адресует драйвер, в товремя как младший номер интерпретируется самим драйвером и можетиспользоваться для различных целей. Например, используя различныемладшие номера, процесс может получить доступ к разным разделам же!сткого диска, обслуживаемого одним драйвером.Во многих случаях использование различных младших номеров позволяетнескольким процессам осуществлять одновременную независимую работус устройством (или псевдоустройством).
Каждый младший номер при этомсоответствует логическому драйверу, поддерживающему собственныеwww.books-shop.comГлава 5.структуры данных при работе с конкретным процессом. Типичным приме!ром могут служить псевдотерминалы. В таких случаях процессу требуетсяполучить доступ к устройству, при этом его не интересует его младшийномер, поскольку различие в младших номерах не отражает различие вфункциональности.
Типичным примером являются сетевые протоколы,чаще всего реализованные в виде соответствующих драйверов. Сетевыесоединения, основанные на одном и том же протоколе (и, следовательно,работающие с одним и тем же драйвером), используют различные млад!шие номера для доступа к драйверу. Это позволяет драйверу обеспечиватьобработку нескольких сетевых соединений, для каждого из которых под!держиваются собственные структуры данных. Если процессу необходимоустановить сетевую связь, ему безразлично, какой младший номер будет удрайвера, главное, чтобы он еще не использовался.Рис.
5.5. Доступ к устройству через различные специальные файлыwww.books-shop.com337Драйверы устройствВозможным сценарием доступа к такому устройству может являться пере!бор различных младших номеров (соответствующих специальных файлов),пока операция openне завершится успешно. Это будет гарантировать,что процесс получил в свое распоряжение отдельное логическое устройст!во. Другой сценарий возлагает всю работу по поиску неиспользуемогомладшего номера устройства на специальные драйверы, получившие на!званияКогда процесс открывает специальный файл устройства, происходит ини!циализация соответствующего snode и вызов функцииреа!лизованной в файловой системе specfs, о которой только что говорилось.Эта функция, в свою очередь, вызывает функцию драйвера ххореппе!редавая ей в качестве аргумента указатель на номера устройства, сохра!ненного в поле s_dev snode. Одной из схем реализации клонов являетсяиспользование зарезервированного младшего номера.
Когда процесс от!крывает специальный файл устройства с этим номером, функцияххорепвыбирает неиспользуемый младший номер и соответственномодифицирует данные snode (с помощью указателя на vnode, передавае!мые ейПоскольку доступ процесса к драйверу осуществля!ется через vnode файловой системы specfs, все последующие операции бу!дут использовать новый младший номер. Таким образом, процесс получитдоступ к новому логическому устройству.
Эта схема приведена на рис. 5.6.Рис. 5.6. Создание клонов с помощью зарезервированного младшего номераClone (англ.) — размножаться.www.books-shop.com3385.ввода/выводаДругой подход заключается в использовании специального драйвера, обес!печивающего создание клонов, — драйвера клонов (clone driver). При этомвсе драйверы, чье "размножение" обеспечивается таким образом, имеютодин и тот же старший номер, адресующий драйвер клонов. Младший но!мер адресует собственно драйвер, т. е. представляет собой старший номерреального устройства, для которого создается клон.
Примеры использова!ния такой схемы можно обнаружить для драйверов системы STREAMS, спомощью которых часто реализуются сетевые протоколы и терминальныйдоступ, включая псевдотерминалы. Это можно заметить, рассмотрев под!робный список файлов, отвечающих за эти устройства:$!1crwrwcrwcrwrwrw111111rootrootrootrootrootrootsyssyssyssyssys11,11,11,11,11,11,4453404241Oct 31 16:36Oct 31 16: 36Nov 3 1995Nov 3 1995Oct 31 16:36Nov 3 1995arpiptcpВ данном случае старший номер всех драйверов равен 11 — это драйверклонов.
Если проанализировать информацию файла, скажем, tcp, To станетпонятно, что старший номер драйвера этого протокола равен 42, для фай!ла tcp он представлен младшим номером устройства. Когда процесс от!крывает этот файл, производится вызов функции clopen() драйвера кло!нов, которой передаются номера устройства.
Функция clopen() исполь!зует младший номер для поиска требуемых точек входа драйвера TCP вкоммутаторе устройств cdevswf[] После этого clopen () вызывает про!цедуру хxореn() драйвера, в данном случае tcpopen(), передавая ей ука!затель на номера устройства и флаг CLONEOPEN. В ответ на это t c p o p e n ( )генерирует неиспользуемый младший номер, создает отдельный логиче!ский драйвер (т. е. копирует необходимые структуры данных) и соответст!вующим образом модифицирует полеиндексного дескрипторафайловой системы specfs. Таким образом, для получения уникальногоTCP!соединения процессу нет необходимости самостоятельно производитьпоиск неиспользуемого младшего номера.Встраивание драйверов в ядроДрайвер устройства является частью кода ядра операционной системы иобеспечивает взаимодействие других подсистем UNIX с физическими илипсевдоустройствами.