Next: Bibliography Up: Философия ОС UNIX Previous: Основные концепции UNIX   Contents

Subsections

Файлы

Имена файлов

Файлы -- это часть ресурсов, которыми распоряжается UNIX, имена файлов с этой точки зрения являются описывающими объектами.

Каждый файл обладает несколькими (хотя бы одним) полными именами, с помощью этих имён пользователь может обращаться к файлам. Для логической организации имён в реализации системы используются каталоги, это специальные файлы содержащие список имён других файлов. Специальный каталог называемый корневым содержит имена файлов и каталогов, если пройтись по всем ссылкам в корневом каталоге то мы посетим все файлы в файловой системе. Для безопасности в большинстве систем UNIX, каталог может обладать только одним именем, это предотвращает появление циклов в графе файловой системы. Таким образом файловая система образует дерево, листья которого -- это ссылки на файлы-не-каталоги. На рис. [*] показа организация файловой системы.

Figure: title

Необходимость для файлов иметь несколько имён возникает из-за того, что на один и тот же файл можно смотреть с логически-разных точек зрения.

Полное имя файла определяется последовательностью имён каталогов, отделённых косой чертой `/'. Последняя часть полного имени называется просто именем файла.

Например: /usr/share/doc/bash/README

usr -- ссылка в корневом каталоге на каталог usr.

share -- ссылка в каталоге usr на каталог share с полным именем /usr/share

...

README -- ссылка в каталоге bash на файл README c полным именем

/usr/share/doc/bash/README

Имена файлов состоят из символов алфавита принятого в системе, и обычно следуя соглашениям принятым в языке С, буквы нижнего и верхнего регистра различаются, т. е. README, readME, readme -- три разных имени, вероятно трёх разных файлов.


Информация о файле

Каждому файлу кроме имён ставится в соответствие один единственный набор информации об этом файле. Эта информация хранится в файловой системе в структуре, называемой inode(индекс -- не точный русский эквивалент). inode содержит тип файла (см. [*]), права доступа к файлу (см. [*]), время модификации файла, время создания файла и время изменения inode (т. е. информации о файле), а так же расположение файла на диске.

Современные системы поддерживают так называемую виртуальную файловую систему (VFS), т. е. ОС работает со стандартными, ,,виртуальными'' индексами, а то как информация хранится на диске -- дело драйверов файловых систем.

Таким образом для каждого файла не зависимо от имён (которые служат только логической организации файлов) содержится одна информация о том как с этим файлом работать.

Для каждого файла процесс может прочесть информацию о нем с помощью системного вызова stat или fstat, если это открытый файл (см. [*])

Операции над файлами

Пользователь должен уметь запускать программы, а программы должны уметь читать входные данные и записывать результат. В результате мы получаем 3 основные операции: read (читать), write (писать), exec (выполнять).


Обращение к файлам со стороны процессов

Рассмотрим программу на языке С, читающую файл:

#include <unistd.h>
#include <fcntl.h>

int main (int argc, char **argv)
{
    int fd;
    char buf[100];

    fd = open ("file.txt", O_RDONLY);
    read (fd, buf, 100);
    close (fd);
}

fd и buf -- переменные в программе. open, read и close -- стандартной библиотеки, которые просто вызывают (обычно по средствам программных прерываний) функции ядра ОС, носящие такие же названия (такие вызовы называются системными (system call)).

Системный вызов open регистрирует среди информации о процессе обращение к соответствующему файлу и записывает информацию необходимую для работы с файлом. Мы назовём это сессией работы с файлом. Результатом системного вызова является то, что процесс получает число называемое файловым дескриптором (file descriptor), это число идентифицирует обращение к данному файлу среди информации о процессе, т. е. является описывающим объектом для сессии.

Вызов read записывает 100 байт в место памяти buf, прочитанных из файла, на который ссылается дескриптор fd.

Вызов close сообщает системе что процесс больше не будет обращаться к файлу по данному дескриптору.

Каждая сессия работы с файлом содержит указатель на место чтения/записи, соответствующие операции производимые с данным обращением читают или записывают информацию в файле начиная с места определяемого этим указателем; операции также изменяют значение указателя, так чтобы последующие операции чтения или записи работали уже на новом месте в файле, с новыми данными.

Процессы работают не с именами файлов а с дескрипторами. Одна и та же сессия работы с файлом может иметь несколько дескрипторов на него ссылающихся, причем одну и ту же сессию могут использовать несколько процессов одновременно, у каждого из которых будет свой дескриптор ссылающийся на эту сессию. Если процессы читают файл одновременно, то каждый прочтет только часть этого файла, причем процессы не будут заранее знать какую часть. Один и тот же указатель на место чтения процессы будут сдвигать независимо друг от друга.

Для сессий работы с файлами у нас есть следующие системные вызовы:

Для непосредственной работы с открытыми файлами используются следующие системные вызовы:


Типы файлов

Действия, которые выполняются различными системными вызовами, а именно: open, close, exec, read, write, lseek, -- зависят от типа файла. В UNIX эти типы заранее определены (в отличие от других систем, напр. Plan 9), вот они:

Обычные файлы
При записи в обычные файлы информация сохраняется на диске и вы сможете её затем прочитать.

Каталоги
Пользователи (даже root) не могут писать в каталог или запускать его на выполнение. Пользователи могут только читать каталоги. Система берет запись в каталоги на себя.

Трубы
Информация пишется и читается из файла по принципу FIFO (первый зашёл, первый вышел). Т. е. если процессы решат обмениваться данными они могут договориться об имени трубы и передавать по ней данные.

Символьные ссылки
Эти файлы не предназначены для какого либо использования, они призваны заменять дополнительные имена файлов, там где невозможно создать новое имя для файла (жесткую связь), для создания дополнительных имён каталогов, а также в некоторых других случаях. Символьные ссылки -- файлы, содержащие путь к файлу на который они указывают. Когда система получает имя файла содержащее имя символьной ссылке она просто подставляет вместо имени ссылки путь который в ней содержится.

Например в имени /usr/doc/bash/README, /usr/doc -- символьная ссылка содержащая путь ``share/doc'', поэтому при системных вызовах ядро подставляет в строку пути вместо doc share/doc и получает /usr/share/doc/bash/README.

Блочные устройства
Блочные устройства предоставляют выполнять операции чтения и записи, определённые модулем встроенном в ядро, обычно это драйвер устройства. Блочные устройства отличаются тем, что загруженный модуль может выполнять чтение или запись только большими блоками и, обычно, довольно медленно. Ядро кеширует блоки с которыми работает модуль и при этом делает вид, что из данного файла можно производить посимвольное (по-байтовое) чтение. Когда пользователь читает данные определённой длинны, ядро само находит в каких блоках находятся данные, читает их, если их нет в кеше, и возвращает пользователю, только необходимую часть блока.
Символьные устройства
Модуль ядра сам реализует чтение и запись для таких устройств.
Гнезда (Сокеты)
Файлы создаваемые при установлении TCP/UDP соединения, запись в такие файлы равносильна передаче данных используя соответствующий протокол.


Права доступа к файлам

В системе UNIX одновременно могут работать несколько (много) пользователей. Каждый процесс выполняет какую-либо одну пользовательскую задачу, но у разных пользователей могут быть различные задачи. Поэтому присутствие пользователя в системе характеризуется тем, что какой-либо процесс работает от имени этого пользователя. Кроме этого пользователь никак не связан с системой. У каждого процесса есть пользователь от лица которого он работает.

Для ядра системы пользователь это просто число, называемое UID (user identifer) или идентификатор пользователя. Для пользователей с некоторыми UID'ами могут быть связаны осмысленные, ,,человеческие'' имена.

Было бы невозможно работать на ЭВМ, если бы пользователи могли изменять, смотреть данные друг друга без разрешения. Для этого в файловой системе хранится набор прав доступа к файлам (см. [*]). В системе существует понятие группы, объединяющее пользователей обладающих одинаковыми правами.

Итак, для каждого файла в файловой системе хранится идентификатор пользователя -- владельца файла, идентификатор группы которой принадлежит файл, и удостоверение права на выполнение 3-х операций: записи, чтения и выполнения, -- для 3-х категорий пользователей: владельца, членов группы, и всех остальных, не попадающих в первые две категории.

Владелец файла -- пользователь имеющий право изменять индекс файла, т. е. независимо от прав других пользователей только владелец может распоряжаться своими правами и раздавать права другим.

Группа файла -- способ выделить группу пользователей, которые будут обладать другими (обычно большими правами, чем остальные). Так как в UNIX все ресурсы представлены (по крайней мере так задумано) в виде файлов, то права пользователя в системе определяются именно правами на доступ к файлам. Если пользователь хочет дать некоторым другим пользователям особые права для доступа к файлу (файлам), то он создаёт группу и устанавливает идентификатор группы файла равным идентификатору данной группы, устанавливает необходимые права доступа для группы. В итоге пользователи входящие в эту группу (а пользователь может входить во много групп) получают установленные права. Таким образом для того чтобы получить набор прав пользователь должен входить в нужную группу. Группы позволяют разъединить права пользователя на отдельные составляющие, а также делить права между пользователями. Возможно было бы задавать права для каждого пользователя в отдельности, но тогда пришлось бы модифицировать при необходимости права каждого, а при использовании групп достаточно изменить права доступа файла для группы и все пользователи входящие в группы сразу получат другие права. Также можно легко давать и лишать прав пользователя, достаточно включить, исключить его из группы.

Каждый процесс содержит идентификаторы пользователя и групп от имени которых он работает. Процесс содержит

Аналогичные три идентификатора содержаться для группы, также содержится список групп в которые входит процесс. Нас интересуют только фактические идентификаторы, т. к. только они влияют на права доступа к файлам (о других мы поговорим в [*]).

Для процесса обращающегося к файлу набор прав выбирается в следующей последовательности:

  1. Если фактический идентификатор пользователя процесса совпадает с идентификатором пользователя файла (владельца), то выбирается набор прав для владельца этого файла.
  2. Если фактический идентификатор группы процесса совпадает с идентификатором группы файла, то выбирается набор прав для группы.
  3. Если идентификатор группы файла содержится в списке групп которым принадлежит процесс, то опять же выбирается набор прав для группы.
  4. В остальных случаях выбирается набор прав для ,,остальных''.
Выделение фактического идентификатора группы из списка групп процесса связанно с выполнением других операций о которых мы поговорим позже.

Такая последовательность выбора позволяет дать группе меньшие права, чем остальным, или даже лишить себя (владельца) части прав по отношению к остальным пользователям, правда эти возможности редко используются.

Мы знаем что для некоторых файлов мы не можем выполнить некоторые операции, например запись и выполнение для каталога, зачем же им все права доступа? Для каталога право на запись означает возможность создавать файлы в таком каталоге. А право на исполнение даёт возможность использовать каталог, как часть пути для доступа к файлу. Например пользователь может не иметь право читать каталог, но у него будет право на его исполнение, тогда пользователь не сможет прочитать какие файлы содержаться в каталоге, но сможет обратится к файлу в каталоге имя которого он знает.

Существует специальный пользователь от лица которого системные администраторы выполняют критические для системы действия. Имя такого пользователя root, для него обычно создаётся группа с тем же именем. Особенность этого пользователя в том что он не связан правами доступа к файлам и может выполнять любые физически возможные действия. Обычные пользователи не должны работать от лица root'а, обычно у системного администратора есть пароль для входа в систему как root, администратор запускает некоторые системные программы от имени root'а чтобы внести изменения, касающиеся всех пользователей системы.

Права доступа к файлу обычно записываются в одну строчку. Такую информацию выдаёт команда ls:

drwxr-xr-x   13 root     root          312 Ноя  8 15:20 usr
первая строка символов -- это тип и права доступа к файлу, d -- тип файла, в данном случае каталог (directory), следующие три символа (rwx) -- права доступа для владельца файла (ему разрешены чтение (r, Reading), исполнение (x, eXecution) и запись (w, Writing). Следующая тройка символов для группы файла, пользователи из группы могут читать и писать в файл, на месте символа w стоит прочерк, означающий запрет на запись. Аналогично для всех остальных пользователей. Число тринадцать -- количество ссылок на файл, т. е. количество имён файла в файловой системе плюс количество процессов, которые работают с этим файлом. Первое слово root -- имя владельца файла, второе -- имя группы файла, дальше идёт дата модификации и имя файла.

Изменение прав доступа

Процессы могут изменять права доступа к файлу по своему усмотрению, если они являются владельцами файла. Насколько я знаю только root, может изменить владельца файла, таким образом большинство владельцев файлов являются их создателями. Процесс может изменить группу файла, если это одна из групп в которые входит этот процесс (т. е. это фактический идентификатор группы процесса или один из идентификаторов содержащимся в списке групп процесса). Для изменения группы и/или владельца файла используется системный вызов chown. Для изменения прав доступа используется вызов chmod.

Работа с файловой системой.


next up previous contents
Next: Bibliography Up: Философия ОС UNIX Previous: Основные концепции UNIX   Contents
Victor Nazarov 2004-04-14