Новые книги

Эта книга – полное руководство по системному анализу клиентского опыта и лояльности. В ней на примере кейсов из реальной практики подробно описывается, как можно применить методику оценки лояльности в любом бизнесе.

Книга будет полезной директорам по маркетингу и развитию, маркетологам и всем, кто интересуется темой клиентоориентированности.

На русском языке публикуется впервые.
Книга "Фундаментальные алгоритмы и структуры данных в Delphi" представляет собой уникальное учебное и справочное пособие по наиболее распространенным алгоритмам манипулирования данными, которые зарекомендовали себя как надежные и проверенные многими поколениями программистов. По данным журнала "Delphi Informant" за 2002 год, эта книга была признана сообществом разработчиков прикладных приложений на Delphi как «самая лучшая книга по практическому применению всех версий Delphi».

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

Несмотря на то что книга рассчитана в первую очередь на профессиональных разработчиков приложений на Delphi, она окажет несомненную пользу и начинающим программистам, демонстрируя им приемы и трюки, которые столь популярны у истинных «профи». Все коды примеров, упомянутые в книге, доступны для выгрузки на Web-сайте издательства.

ГЛАВА 7. Устройства и файловые системы



      ИМЯ: c

c Быстрая очистка экрана

НАЗНАЧЕНИЕ

Выводит последовательность символов очистки экрана с использованием быстрой программы на языке Си. Код очистки, указанный в тексте программы, следует изменить в соответствии с используемым терминалом.

ФОРМАТ ВЫЗОВА

   c    

ПРИМЕР ВЫЗОВА

    c         Очистка экрана    

ТЕКСТ ПРОГРАММЫ

       1  char id[] = "@(#) c v1.0 Fast clear screen Author: Russ Sage";
                            Быстрая очистка экрана
       3  #define FF "\014"
       5  main()
       6  {
       7          if (write(1, FF, 1) == -1)
       8                  write(2,"c: write error to stdout\n",25);
                               ошибка записи в стандартный вывод
       9  }    

ОПИСАНИЕ

Зачем нам нужна программа c?

В System V уже имеется команда для очистки экрана терминала - это команда clear. Она работает путем определения типа вашего терминала и затем вывода на экран символа очистки для данного терминала. Все прекрасно, но есть один существенный недостаток: она очень МЕДЛЕННАЯ!

Мы же хотим как можно быстрее выполнить очистку экрана. Самой быстрой операцией ввода-вывода в системе является прямой системный вызов для чтения или записи. Мы применяем этот вызов, а также выполняем небольшую проверку ошибок для определения доступности стандартного устройства вывода.

Что делает c?

Программа 'c' выводит на экран символ очистки настолько быстро, насколько быстро может выполняться операция ввода-вывода в UNIX. Применяя прямой системный вызов, мы избавляемся от необходимости запускать другую программу. Поэтому программа 'c' работает очень быстро. Мы уверены, что точно такую же функцию можно вызывать как команду Си-shell (поместить в csh alias), поэтому данная программа наиболее полезна тем, кто работает в System V.

Для того чтобы определить, какой символ очистки соответствует вашему терминалу, найдите строку с обозначением cl в файле termcap. Это и есть то значение, которое вы должны вручную вставить в данную программу. Если вы работаете не на таком терминале, для которого эта программа написана, то данная команда будет работать неверно.

ПОЯСНЕНИЯ

Первым делом мы должны найти в файле termcap код очистки экрана. Для терминала Apple это код ^L, а для vt52 это \EH\EJ. Как только вы найдете этот код, вставьте его в оператор define в строке 3 или сразу в оператор write в строке 7. В приведенном примере в качестве символа очистки экрана используется ^L.

Наиболее быстрым способом передачи символа в файл является непосредственное выполнение оператора write. Поскольку терминалы являются файлами, мы можем выполнять запись непосредственно в них, пользуясь преимуществом предопределенных дескрипторов файла 0,1 и 2.

Системный вызов write в строке 7 посылает символ очистки в файл с дескриптором 1, который является стандартным устройством вывода. Если операция записи неудачна (по ряду причин), то в файл с дескриптором 2, т.е. на стандартное устройство регистрации ошибок, выводится сообщение об ошибке. Здесь не проверяется, успешно ли завершилась запись на стандартное устройство регистрации ошибок. Если ошибка все-таки возникнет, то мы ее увидим.

Программа не использует НИКАКИХ возможностей стандартного ввода-вывода (stdio). НИКОГДА нельзя смешивать системные вызовы ввода-вывода (т.е. вызовы из раздела (2) документации по системным функциям, например read или write) со стандартными вызовами ввода-вывода (т.е. вызовами из раздела (3), такими как getchar и printf). Дополнительный буфер, который создается при выполнении функций stdio, не согласован во времени с системными вызовами, поэтому все выходные сообщения перемешиваются.

Еще один аспект, о котором мы должны помнить, принимая решение об использовании системных вызовов, это преимущество получения как можно более короткого объектного кода. Небольшая программа загружается и работает быстрее. Для того, чтобы ненужные подпрограммы стандартного ввода-вывода не включались в наш объектный модуль, в исходном тексте программы не делается никаких ссылок на подпрограммы stdio. Тем не менее, ваша система могла их каким-то образом включить. Так поступает XENIX, а вместе с stdio вызывается malloc и все остальное. Вы можете просмотреть таблицу символов вашего объектного модуля с помощью nm(1) или nlist(2). Вы увидите весь мусор, который был добавлен в ваш объектный модуль. Не так редко мы получаем 6 Кб кода всего лишь для одного оператора printf! Приучайтесь программировать непосредственно на ассемблере, чтобы достичь того, что вам нужно.

ИССЛЕДОВАНИЯ

Когда эта программа была написана, возник вопрос: "Каким образом мы можем проверить неудачу записи на стандартное устройство вывода?". Раньше такой вопрос не стоял, но показалось, что неплохо было бы это сделать. Решение было найдено на страницах описания sh(1). Способ, которым можно вызвать ошибку выполнения записи на стандартное устройство вывода, заключается в том, что нужно закрыть дескриптор файла стандартного устройства вывода. Это легко делается с помощью команды exec, которая является внутренней по отношению к shell:

$ exec >&-Эта команда переназначает файловый дескриптор 1 стандартного вывода (обозначение >) на дескриптор файла (&) закрытого устройства (-). Такой эксперимент может оказаться полезным для более полной отладки ваших программ.

ДИСКОВЫЕ УСТРОЙСТВА

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

Основное отличие между дисками и терминалами заключается в том, что диски являются блочными устройствами, а терминалы - символьными. Вместо того, чтобы выполнять обмен информацией по одному символу, диски обмениваются блоками по 512 или 1024 символа. Имеются команды, которые управляют разбиением на блоки и буферизацией, что делает возможным выполнение блочных операций ввода-вывода.

РАЗБИЕНИЕ ДИСКОВ НА РАЗДЕЛЫ

Части, или области диска, известны как разделы. Раздел может содержать файловую систему, которая сгенерирована командой mkfs(1), или же может содержать неструктурированные данные, доступ к которым выполняется с помощью команды 'cpio -o'.

В системе XENIX управление разделами осуществляется программой fdisk, которая концептуально подобна своей тезке в системе MS-DOS. В других системах UNIX используются другие имена. Например, в системе AT&T 7300 UNIX PC используется программа iv, что значит "format" (хотите верьте, хотите нет). Как упоминалось ранее, обычно разделы содержат одну файловую систему. В настоящее время в системах XENIX и SCO XENIX у вас есть возможность "разделить раздел" на более мелкие части для получения большего количества файловых систем. Это сделано по той причине, что машины с системами DOS и XENIX ограничены четырьмя дисковыми разделами, а у вас может возникнуть желание иметь больше файловых систем, чем число доступных разделов. В системе AT&T 7300 UNIX PC управление разделами диска осуществляется по списку начальных номеров дорожек. Вы можете создать столько разделов, сколько хотите. Каждый компьютер имеет свои преимущества и недостатки.

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

    |
    | brw-------   1 sysinfo  sysinfo  1,  0 Feb 18 17:07 /dev/hd00
    | brw-------   1 sysinfo  sysinfo  1, 15 Feb 18 16:59 /dev/hd01
    | brw-------   1 sysinfo  sysinfo  1, 23 Feb 18 16:59 /dev/hd02
    | brw-------   1 sysinfo  sysinfo  1, 31 Feb 18 16:59 /dev/hd03
    | brw-------   1 sysinfo  sysinfo  1, 39 Feb 18 16:59 /dev/hd04
    | brw-------   1 sysinfo  sysinfo  1, 47 Feb 18 17:07 /dev/hd0a
    | brw-------   1 sysinfo  sysinfo  1, 55 Feb 18 17:09 /dev/hd0d
    | crw-------   1 sysinfo  sysinfo  1,  0 Feb 18 16:59 /dev/rhd00
    | crw-------   1 sysinfo  sysinfo  1, 15 Feb 18 16:59 /dev/rhd01
    | crw-------   1 sysinfo  sysinfo  1, 23 Feb 18 16:59 /dev/rhd02
    | crw-------   1 sysinfo  sysinfo  1, 31 Feb 18 16:59 /dev/rhd03
    | crw-------   1 sysinfo  sysinfo  1, 39 Feb 18 16:59 /dev/rhd04
    | crw-------   1 sysinfo  sysinfo  1, 47 Feb 18 16:59 /dev/rhd0a
    | crw-------   1 sysinfo  sysinfo  1, 55 Feb 18 17:09 /dev/rhd0d
    |

Имена файлов с префиксом hd указывают блочные устройства, а с префиксом rhd - "неструктурированные" символьные устройства. Не все символьные устройства являются неструктурированными блочными устройствами. Терминалы являются символьными устройствами, как мы уже видели ранее в данной главе. В табл. 7-2 показаны различные характеристики этих двух типов устройств.

Таблица 7-2
Сравнение блочных и символьных устройств

Блочное устройство Символьное устройство
/dev/hd0, /dev/fd0 /dev/rhd0, /dev/rfd0
буфер управляется ядром системы, медленное устройство буферизация отсутствует, быстрое устройство
произвольное размещение блоков данных последовательное размещение блоков данных
доступ через файловую систему доступ непосредственно на диск
cpio -p cpio -o, -i
mkfs, mount, df, du, fsck, fsdb tar

Как видите, существует много способов работы с устройствами.

Давайте рассмотрим устройство /dev/hd01 из приведенного выше списка. Если вы хотите адресоваться к физическому разделу на диске как к блочному устройству, вы можете создать на нем файловую систему. Для этого вам нужно выполнить следующую команду, которая создаст файловую систему размером 5000 Кб (5 Мб) на жестком диске:

       # mkfs /dev/hd01 5000

Внутри раздела (размером не менее 5000 Кб) размещается файловая система. Файловая система содержит суперблок, списки свободных блоков и т.п., то есть все, что необходимо для хранения файлов, которые размещаются здесь. Однако, создание файловой системы совсем НЕ означает, что вы сразу же можете получить к ней доступ. Сначала вам необходимо смонтировать файловую систему. Команда для выполнения этой операции может иметь такой вид:

       # mount /dev/hd01 /mount_pt

Файлы могут быть помещены в дисковый раздел командами mv или cp, путем переадресации вывода в каталог с этим именем, например, >/mount_pt/file.

Для использования раздела диска в качестве области неструктурированных данных, а не блочного устройства, применяйте файл с именем символьного устройства, которое начинается с буквы r. Например, для использования того же устройства, что и в предыдущем примере, в качестве неструктурированного устройства, укажите имя /dev/rhd01. (Из списка устройств вы видите, что это символьное устройство, так как права доступа в первой колонке начинаются с символов crw, а не brw). Это устройство (и соответствующий раздел) в данный момент не имеет файловой системы и является просто набором байтов. Единственным ограничением является то, что вы можете записать в этот раздел не более 5 Мб данных.

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

       $ find . -print | cpio -ocBv > /dev/rhd01    

ИЗУЧЕНИЕ ДАННЫХ

Когда данные находятся на диске, их можно изучить более тщательно, чем с помощью команд cat, more и других. Делается это командой od(1), которая выдает дамп файла устройства, как показано в следующем примере:

       $ od -c /dev/hd01

Если бы вы получали дамп файла НЕСТРУКТУРИРОВАННОГО устройства (/dev/rhd01), то это выглядело бы точно так же. Единственное отличие заключается в том, как драйвер осуществляет доступ к данным. Формат, в котором будут выводиться данные, зависит от того, какой командой производилось копирование: cpio, tar, mkfs или какой-то иной. Некоторые другие способы получения данных с устройства:

       $ cat /dev/hd01
       $ cat < /dev/hd01
       $ tail /dev/fd0

Если вы дампируете файл устройства, содержащего файловую систему, то данные будут представлять собой неупорядоченные блоки по 512 байт. В одном месте вы можете увидеть списки каталогов. Другими словами, одно и то же устройство может рассматриваться двумя совершенно разными способами: как файловая система и как набор неструктурированных битов. Хотя выполнение чтения двумя этими способами может быть поучительным, в большинстве случаев у вас не возникнет желания выполнить ЗАПИСЬ информации на одно и то же устройство двумя способами, поскольку, например, неструктурированное устройство не будет ничего знать о файловой системе в данном разделе и может затереть данные, относящиеся к файловой системе.

Теперь, когда вы знаете, как осуществить доступ к диску, мысленно вернемся к главе 2 и программам копирования. Командный файл cpiobr использует для копирования файлов неструктурированное дисковое устройство /dev/rfd0, в то время как autobkp использует файловую систему.

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

Итак, поскольку вы обычно должны выбрать тот или иной метод использования раздела диска, то ничто не мешает вам завести на устройстве все разделы одинакового типа. Обычным подходом является создание файловых систем во всех возможных разделах, чтобы они могли содержать файлы. Тем не менее, вы можете сочетать файловую систему с "неструктурированными" разделами любым способом, который вам нравится. Одной из возможных схем является использование одного раздела (fd01) в качестве неструктурированного устройства для копирования файлов командой "cpio -o". Этот раздел занимает почти весь диск, но какая-то часть отводится для размещения второго раздела с файловой системой (fd02). Распределенное пространство содержит некоторые справочные (help) файлы и текстовый файл с именами файлов, находящихся в неструктурированном разделе. Такое разбиение на разделы использует преимущества обоих способов. Для того чтобы получить данные, скопированные командой cpio, вы вводите команду "cpio -i < /dev/rfd01". Для получения данных из второго раздела, вы вводите команду "mount /dev/fd02 /mnt", а затем используете команды ls, file, grep и другие, которые относятся к файловой системе. В этом случае раздел с файловой системой служит для документирования неструктурированного раздела.

ЗАГРУЖАЕМЫЙ ДИСК И АВТОНОМНЫЙ shell (SASH)

Инсталляция системы UNIX на жесткий диск обычно выполняется с помощью автономного shell (SASH, standalone shell). Иногда эта операция выполняется с магнитной ленты, но легче всего использовать гибкий диск. Возникает вопрос: "Как загрузить UNIX с гибкого диска?"

Картина следующая: гибкий диск имеет один раздел или даже может быть разделен на корневой раздел и раздел пользователей. В любом случае гибкий диск имеет файловую систему, созданную другой системой и помещенную на диск. Первый блок файловой системы является загружаемой записью, которая размещается на носителе с помощью команды dd. Команда dd копирует байты, начиная с самого начала устройства. Загрузочная запись содержит код, необходимый для запуска системы UNIX с диска.

Второй блок - это суперблок, своего рода главный каталог файловой системы. В нем находятся индексные дескриптооы файлов, содержащие информацию о каждом файле, а также список доступных свободных блоков. Корневая файловая система имеет также вариант ядра для гибкого диска, который загружается и запускает shell точно так же, как это делает его старший брат (ядро системы для жесткого диска) для всей системы в целом. Вы даже можете смонтировать инсталляционный диск на жесткий диск с другой системой и выполнять команды копирования. Ограничивающим фактором является размер одного инсталляционного диска. Самый большой объем гибкого диска на машинах PC - 1.2 Мб (используется на PC AT), что вполне достаточно. Можно уместить почти всю программу загрузки, которая необходима для запуска многопользовательской системы с гибкого диска.

Как только ядро системы с гибкого диска загружено, имеется полная файловая система со всеми файлами устройств. Ядро монтирует раздел жесткого диска (предполагается, что жесткий диск был разбит на разделы) и копирует на него файлы в формате файловой системы. Вот как это выглядит:

       # mount /dev/hd01 /mnt <-вызов с гибкого диска для монтирования
                         первого раздела жесткого диска
       # copy /unix /mnt      <-копирование ядра жесткого диска в раздел
                         жесткого диска    

ОБНОВЛЕНИЕ ФАЙЛОВОЙ СИСТЕМЫ

Мы описали суперблок как запись с ключевой информацией о размере и содержимом файловой системы. Причиной разрушения файловой системы обычно являются проблемы, возникающие в суперблоке. Команда sync(1) выполняет запись образа суперблока на диск, тем самым обновляя его. Иногда эта операция должна выполняться автоматически и постоянно для того, чтобы образы суперблока на диске и в памяти были одинаковы. В настоящее время в System V включена программа update, которая запускается из загрузочного файла /etc/rc. Она живет в системе и исполняет команды sync и sleep. В результате информация о состоянии файловой системы на диске хранится со всеми текущими изменениями, произведенными с самой файловой системой. Если у вас нет такой программы, вы можете написать командный файл на языке shell, которая работает в цикле, вызывая команду sync через соответствующие интервалы команды sleep. Запустите этот командный файл в фоновом режиме, чтобы поддерживать целостность файловой системы.

МОНТИРОВАНИЕ ФАЙЛОВЫХ СИСТЕМ

Давайте рассмотрим, что происходит, когда файловая система монтируется в древовидной структуре системы. На рис. 7 -3 показано, как взаимодействуют между собой индексные дескрипторы (inodes) двух файловых систем.

Рисунок 7-3
Монтирование одной файловой системы в другую

В примере, показанном на рис. 7-3, файловая система из раздела 2 монтируется в корневой файловой системе (раздел 1) в каталог /usr. Однако мы помним, что каждая файловая система имеет свой собственный корневой каталог. В каждой файловой системе нумерация индексных дескрипторов файла начинается с числа 2, поэтому номера индексных дескрипторов дублируются в двух файловых системах. Это и является причиной, по которой не могут быть образованы связи между файлами, находящимися в разных файловых системах.

Одним из атрибутов корневого каталога является то, что номер его индексного дескриптора равен 2. Это значение может быть проверено в корневом каталоге командой "ls -lid /". Каталог /usr - это просто еще один файл (а именно каталог) в корневой файловой системе. Этот каталог может содержать файлы и подчиненные каталоги, которые хранятся в разделе 1. После выполнения команды "mount /dev/hd02 /usr" корневой каталог раздела 2 (индексный дескриптор 2) помещается в каталог /usr (индексный дескриптор 245). Если какие-либо файлы существуют в каталоге /usr в разделе 1, они остаются там, но получить доступ к ним вы не можете. Единственным способом увидеть их является размонтирование файловой системы, которая была смонтирована на их место. Хитрость команды mount заключается в том, что она представляет новый раздел как бы принадлежащим реальному корневому разделу. В сущности, это позволяет иметь безграничную файловую систему.

Механизмом, который позволяет производить это, является таблица смонтированных устройств, находящаяся внутри ядра системы. Когда выполняется обращение к файлу, его индексный дескриптор определяет маршрут, по которому находится данный файл. Если в таблице смонтированных устройств имеется запись, то этот маршрут ведет на другой раздел диска или в другую файловую систему. Для того чтобы убедиться, что вновь смонтированная файловая система уникальна, посмотрите индексный дескриптор каталога /usr сначала из корневого каталога (командой "ls -li /", индексный дескриптор 245), а затем из другой файловой системы (ls -ldi /usr, индексный дескриптор 2).

КАК ПОЛУЧИТЬ ПОБОЛЬШЕ ИНФОРМАЦИИ О ФАЙЛОВОЙ СИСТЕМЕ?

Как указывалось ранее, файловая система размещается внутри раздела на диске. Файловые системы создаются командой mkfs(1), поддерживаются командой fsck(1), отлаживаются командой fsdb(1), а первый доступ к ним осуществляется командой mount(1). Каталог /usr/include содержит все включаемые файлы для использования в программах на языке Си, реализующих эти команды. Таким образом, этот каталог представляет собой прекрасную возможность для поиска информации о файловой системе, поскольку включаемые файлы содержат глобальные определения, используемые подпрограммами файловой системы. В документации Bell Labs (в руководстве программиста) также описаны некоторые внутренние таблицы, используемые файловой системой.

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


      ИМЯ:  mntf

mntf Монтирование и размонтирование гибкого диска

НАЗНАЧЕНИЕ

Монтирует и размонтирует устройство гибкого диска в каталоге как файловую систему с возможностью записи/чтения или только чтения.

ФОРМАТ ВЫЗОВА

   mntf [-d] [-h] [-l] [-r] [-s]Опции:

-d размонтирование гибкого диска из корневой файловой системы

-h использование устройства с высокой плотностью записи (а не с низкой)

-1 использование устройства 1, а не устройства 0

-r монтирование гибкого устройства как файловой системы с возможностью только чтения

-s использование имен устройств, принятых в System V

По умолчанию выполняется монтирование гибкого диска 0 в каталог /mnt.

ПРИМЕР ВЫЗОВА

   mntf -d -1Размонтирование гибкого диска на устройстве 1.    

ТЕКСТ ПРОГРАММЫ

       1   :
       2   # @(#) mntf v1.0  Mount floppies  Author: Russ Sage
                      Монтирование гибких дисков
       4   CMD="/etc/mount"
       5   DIR="/mnt"
       6   DRIVE="0"
       7   DENSITY="48ds9"
       8   SYSTEM="xenix"
       10  if [ $# -gt 0 ]
       11    then  for ARG in $*
       12          do
       13            case $ARG in
       14             -d)  CMD="/etc/umount"
       15                  DIR="";;
       16             -h)  DENSITY="96ds15";;
       17             -1)  DRIVE="1"
       18                  if [ -d /mnt1 ]
       19                    then DIR="/mnt1"
       20                    else echo "the directory /mnt1 does not exist" >&2
                                 нет каталога /mnt1
       21                         echo "using the directory /mnt instead"   >&2
                                 используется каталог /mnt
       22                  fi;;
       23             -r)  DIR="$DIR -r";;
       24             -s)  SYSTEM="sysv";;
       25             *)   echo "mntf: invalid argument $ARG"          >&2
       26                  echo "usage: mntf [-d] [-h] [-1] [-r] [-s]" >&2
       27                  echo "      -d  dismount"                   >&2
       28                  echo "      -h  high density"               >&2
       29                  echo "      -1  use drive 1"                >&2
       30                  echo "      -r  read only"                  >&2
       31                  echo "      -s  System V device"            >&2
       32                  echo " default: mount XENIX drive 0 48 tpi to " >&2
       33                  echo "         /mnt as a read/write filesystem" >&2
       34                  exit 1;;
       35             esac
       36         done
       37  fi
       39  case $SYSTEM in
       40  sysv)   $CMD /dev/fp${DRIVE}21 $DIR;;
       41  xenix)  $CMD /dev/fd${DRIVE}${DENSITY}  $DIR;;
       42  esac    

ПЕРЕМЕННЫЕ СРЕДЫ ВЫПОЛНЕНИЯ

CMD Основная команда, подлежащая выполнению
DIR Каталог, в котором производится монтирование устройства
DENSITY Плотность записи в виде, указанном в имени устройства
DRIVE Номер устройства, начиная с 0
SYSTEM Тип имени устройства, принятый в UNIX'е

ОПИСАНИЕ

Зачем нам нужен командный файл mntf?

В машинах с гибким диском это устройство часто используется в повседневных операциях. Оно применяется в качестве источника при инсталляции системы и как обычный носитель для операций копирования.

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

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

Поскольку использование гибких дисков включает в себя взаимосвязанные шаги монтирования и размонтирования, то было бы вполне естественным применять одну команду с соответствующими опциями для выполнения монтирования и размонтирования. Однако UNIX так не делает. Наш командный файл mntf объединяет эти две функции в одной команде для упрощения работы с гибким диском. Для того чтобы сделать нашу программу более независимой, мы предусмотрели в ней поддержку устройств системы XENIX наравне с устройствами System V. (Системы Berkeley (BSD) не так часто используют гибкие диски, поэтому мы не пытались иметь с ними дело.)

Что делает mntf?

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

Действие программы по умолчанию заключается в монтировании гибкого диска низкой плотности записи, находящегося в устройстве 0, в каталог /mnt. Имеется много опций, чтобы попросить программу mntf сделать то, что вам нужно. Опция -h поддерживает диск высокой плотности (1.2 Мб). В машинах PC AT первое из устройств гибких дисков имеет 96 дорожек на дюйм, объем 1.2 мегабайта, но может также читать и писать гибкие диски с более низкой плотностью. Второй гибкий диск является устройством низкой плотности с 48 дорожками на дюйм и объемом 360 килобайт.

Опция -1 (цифра один, а не буква l) выполняет монтирование гибкого диска в устройстве 1, а не 0. Опция -r монтирует файловую систему с возможностью ТОЛЬКО ЧТЕНИЯ. Для РАЗМОНТИРОВАНИЯ диска вместо монтирования используется опция -d. Если применяется опция -s, имя устройства изменяется таким образом, чтобы оно соответствовало системе System V, а не XENIX. Это незначительная проблема, поскольку схемы именования не очень отличаются. Данная программа создана для системы XENIX и обеспечивает наилучшие возможности именно в ней.

Не все опции совместимы друг с другом, но проверка на совместимость не выполняется. Например, команда "mntf -d -r" пытается размонтировать файловую систему с возможностью только чтения, а команда UNIX unmount, которая выполняет эту операцию, отбрасывает ее, выдавая сообщение об ошибке. В целях упрощения мы отказались от проверки соответствия опций, а вместо этого предоставили UNIX'у право выдавать сообщения об ошибках для информирования пользователя о возникших проблемах. Если вы хотите, чтобы эту программу мог применять относительно неопытный пользователь, вам нужно вставить в нее выполнение таких проверок.

ПРИМЕРЫ

   1.  $ mntf -s

Монтирование гибкого диска как файловой системы с возможностью записи-чтения и с использованием имен устройств, принятых в System V.

   2.  $ mntf -h -1 -r

Монтирование гибкого диска высокой плотности записи на устройстве 1 как файловой системы с возможностью только чтения и с использованием формата имен устройств, принятого в XENIX. Эта команда должна закончиться неудачей (устройство 1 имеет низкую плотность).

   3.  $ mntf -d -h

Размонтирование файловой системы на устройстве 0 с высокой плотностью записи и с использованием имен устройств, принятых в XENIX.

ПОЯСНЕНИЯ

Для того чтобы максимально упростить программу, все фактически выполняемые команды помещены в текстовые строки. Это позволяет достичь большей гибкости при написании программы. Результатом анализа командной строки является формирование команды, которая выполняется в конце программы mntf.

В строках 4-8 инициализируются установки по умолчанию. Переменная CMD содержит команду UNIX, которая в итоге должна быть выполнена, по умолчанию это команда mount. Переменная DIR указывает каталог, в который должно быть смонтировано устройство, по умолчанию это каталог /mnt. Переменная DRIVE является номером устройства (по умолчанию 0) и используется для формирования корректного имени устройства. Переменная DENSITY по умолчанию установлена для носителя низкой плотности, т.е. 48 дорожек на дюйм, двусторонняя дискета с 9 секторами на дорожку (48ds9).

В строке 10 проверяется, указаны ли в командной строке какие-либо аргументы. Если количество аргументов больше нуля, последовательно проверяется каждый аргумент. Если какой-либо из аргументов соответствует образцам в строках 13-35, то он изменяет содержимое командной строки.

Строка 14 управляет опцией -d для размонтирования гибкого диска. Переменная CMD изменяется на umount вместо mount. После этого переменной DIR присваивается нулевое значение, поскольку команде umount требуется не каталог, а только имя устройства. Переменная DIR должна быть частью строки с командой для того, чтобы мы могли использовать одну и ту же "заготовленную" командную строку для всех вариантов. В данном случае мы устанавливаем эту переменную в нуль, а shell при синтаксическом разборе удаляет ее из командной строки.

В строке 16 выполняется изменение плотности записи используемого носителя. Обращение к различным типам носителей выполняется по именам файлов устройств. Каждое имя указывает драйвер устройства, который работает с соответствующей аппаратурой. Устройство высокой плотности может работать в режимах как высокой, так и низкой плотности записи. Однако если вы укажете имя устройства с высокой плотностью записи, а на самом деле оно имеет низкую плотность, то драйвер работать не будет из-за ошибок чтения.

ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ ОБ ИМЕНАХ УСТРОЙСТВ

Ниже приводится список, полученный командой ls в каталоге dev для машины XT, в которой нет устройств высокой плотности записи. Этот список позволяет проиллюстрировать, каким образом осуществляется обращение к именам устройств:

    |
    |  32 brw-rw-rw-  3 bin   bin   2,  4 Jun 25 09:25 /dev/fd0
    |  32 brw-rw-rw-  3 bin   bin   2,  4 Jun 25 09:25 /dev/fd048
    | 126 brw-rw-rw-  1 root  root  2, 12 Feb 18 17:09 /dev/fd048ds8
    |  32 brw-rw-rw-  3 bin   bin   2,  4 Jun 25 09:25 /dev/fd048ds9
    | 125 brw-rw-rw-  1 root  root  2,  8 Feb 18 17:09 /dev/fd048ss8
    | 127 brw-rw-rw-  1 root  root  2,  0 Feb 18 17:09 /dev/fd048ss9
    | 131 brw-rw-rw-  3 root  root  2,  5 Feb 18 17:09 /dev/fd1
    | 131 brw-rw-rw-  3 root  root  2,  5 Feb 18 17:09 /dev/fd148
    | 129 brw-rw-rw-  1 root  root  2, 13 Feb 18 17:09 /dev/fd148ds8
    | 131 brw-rw-rw-  3 root  root  2,  5 Feb 18 17:09 /dev/fd148ds9
    | 128 brw-rw-rw-  1 root  root  2,  9 Feb 18 17:09 /dev/fd148ss8
    | 130 brw-rw-rw-  1 root  root  2,  1 Feb 18 17:09 /dev/fd148ss9
    |

Крайнее слева число представляет собой номер индексного дескриптора. Мы используем его как ссылку для определения уникального имени файла. Как мы уже отмечали ранее, несколько имен устройств могут относиться к одному и тому же файлу, рассматриваемому с различных точек зрения. Например, в данном списке вы видите, что три устройства имеют индексный дескриптор 32. Второе число слева представляет собой количество связей. Когда оно больше единицы, то это также указывает, что несколько устройств являются на самом деле одним файлом, а следовательно используют один и тот же индексный дескриптор. Следующие два числа являются старшим и младшим номером. Старший номер относится к драйверу устройства, а младший является уникальным номером одного из устройств, управляемых одним и тем же драйвером.

Большинство из этих имен устройств соответствуют определенному шаблону. Они состоят из символов fd (floppy disk - гибкий диск), цифры 0 или 1 (номер устройства), числа 48 (плотность, выраженная в виде количества дорожек на дюйм), символов ss или ds (single-sided - односторонняя или double-sided - двусторонняя дискета) и цифры 8 или 9 (число секторов).

Мы видим по индексным дескрипторам, что устройство fd0 связано с устройствами fd048 и fd048ds9. Самым информативным именем (и самым трудным при вводе с клавиатуры) является имя fd048ds9. Оно точно выражает, к какому устройству и типу носителя мы обращаемся. Для того чтобы упростить указание этого имени, устройство fd048ds9 связывается с более короткими именами. Все три имени файла являются корректными. Следующий список получен на машине AT, в которой имеется устройство высокой плотности:

    |
    | 102 brw-rw-rw-  3 bin  bin  2,  7 Jun 17 14:28 /dev/fd0
    |  95 br--r--r--  2 bin  bin  2,  3 Jun  6 09:23 /dev/fd048
    |  93 br--r--r--  1 bin  bin  2,  2 Jun  6 09:23 /dev/fd048ds8
    |  95 br--r--r--  2 bin  bin  2,  3 Jun  6 09:23 /dev/fd048ds9
    |  92 br--r--r--  1 bin  bin  2,  0 Jun  6 09:23 /dev/fd048ss8
    |  94 br--r--r--  1 bin  bin  2,  1 Jun  6 09:23 /dev/fd048ss9
    | 102 brw-rw-rw-  3 bin  bin  2,  7 Jun 17 14:28 /dev/fd096
    | 102 brw-rw-rw-  3 bin  bin  2,  7 Jun 17 14:28 /dev/fd096ds15
    |  99 brw-rw-rw-  3 bin  bin  2, 11 Jun 26 19:34 /dev/fd1
    |  99 brw-rw-rw-  3 bin  bin  2, 11 Jun 26 19:34 /dev/fd148
    |  97 br--r--r--  1 bin  bin  2, 10 Jun  6 09:23 /dev/fd148ds8
    |  99 brw-rw-rw-  3 bin  bin  2, 11 Jun 26 19:34 /dev/fd148ds9
    |  96 br--r--r--  1 bin  bin  2,  8 Jun  6 09:23 /dev/fd148ss8
    |  98 br--r--r--  1 bin  bin  2,  9 Jun  6 09:23 /dev/fd148ss9
    | 103 brw-rw-rw-  2 bin  bin  2, 15 Jun  6 09:23 /dev/fd196
    | 103 brw-rw-rw-  2 bin  bin  2, 15 Jun  6 09:23 /dev/fd196ds15
    |

Если мы посмотрим на записи с индексным дескриптором 102, начиная с середины списка, то увидим прогрессирующее упрощение имен по мере продвижения к первой записи - устройству 0, которое имеет высокую плотность записи по умолчанию. Для того чтобы обратиться к нему как к устройству с низкой плотностью записи, необходимо использовать имя fd048, а не fd0. Поскольку большинство используемых гибких дисков имеют низкую плотность записи, то имя fd048ds9 является умолчанием в программе mntf. Строка 17 соответствует опции -1 для указания устройства 1 вместо устройства 0. Строки 18-22 проверяют, сиществует ли каталог для монтирования второго устройства. Если вы используете два гибких диска одновременно, то вы не можете монтировать их оба в один и тот же каталог. Для разрешения этой проблемы программа mntf использует для монтирования устройства 1 каталог /mnt1, а не /mnt. Если каталог /mnt1 не существует, по умолчанию используется каталог /mnt, и все хорошо, если вы используете только устройство 1. Однако следует избегать монтирования одного гибкого диска на место второго. Вы можете получить непредвиденные результаты. Если вы собираетесь монтировать два гибких диска, убедитесь, что у вас есть и каталог /mnt, и /mnt1. Строка 23 делает монтируемую файловую систему доступной только для чтения в случае, если была указана опция -r, что выполняется добавлением символов -r к имени каталога. Это не является частью имени каталога, но когда shell выполняет обработку команды, пробела между именем каталога и -r достаточно, чтобы распознать -r как опцию. Строка 24 соответствует опции -s и присваивает переменной SYSTEM значение sysv. Это означает, что нужно использовать другие соглашения об именах устройств. Строки 25-34 выполняют проверку на ошибки в командной строке. Любая опция, отличная от уже проверенных, является ошибкой, поэтому все, что соответствует улавливающей ветке оператора case (*), считается недопустимой опцией. В этом случае выводится синтаксическая подсказка, и программа завершается. В строках 39-42 выполняется вся основная работа. Оператор case действует в соответствии со значением переменной SYSTEM. Если оно равно "sysv", выполняется строка 40. В противном случае выполняется строка 41 для системы XENIX. Обратите внимание, что в нашей версии командного файла mntf в строке sysv имеется только переменная с номером устройства. Если вы используете System V, вы можете добавить переменную для указания плотности записи или другие параметры, которые вам нужны. Строка 41 выполняет версию команды, рассчитанную на систему XENIX. Переменная CMD содержит, как мы отмечали, команду монтирования (mount) или размонтирования (umount). Последовательность символов /dev/fd указывает файл устройства для гибкого диска. Переменная DRIVE равна 0 или 1. Переменная DENSITY указывает устройство с высокой или низкой плотностью записи. Если должна быть выполнена команда монтирования, переменная DIR содержит каталог. Если выполняется размонтирование, значение переменной DIR равно нулю.

ЗАМЕЧАНИЕ ПО ВОПРОСУ БЕЗОПАСНОСТИ

Обычно только суперпользователь (root) может монтировать файловую систему. В больших системах это имеет смысл. Однако на небольших настольных машинах это может быть слишком ограничивающим фактором. Для того чтобы обойти это требование, используйте возможность изменения прав доступа. Чтобы позволить любому пользователю выполнять команды монтирования и размонтирования, примените следующие команды:

       # chown root /etc/mount  <- делает пользователя root владельцем
                            модуля /etc/mount
       # chmod 4511 /etc/mount     и дает возможность выполнять команду mount
                            всем пользователям
       # chown root /etc/umount <- делает то же самое для команды
       # chmod 4511 /etc/umount    размонтирования

Эти команды облегчают всем пользователям работу с гибким диском, но одновременно открывают огромную дыру в защите системы. Если кто-либо уже проложил тропинку прав доступа на гибкий диск (см. главу 9), то монтирование файловой системы продолжит эту тропинку в главную систему и позволит такому пользователю стать суперпользователем всей системы в целом просто с гибкого диска!

Назад | Содержание | Вперед