Пользователи системы



страница30/42
Дата01.12.2017
Размер5.38 Mb.
ТипПрограмма
1   ...   26   27   28   29   30   31   32   33   ...   42

Останов системы


Как уже говорилось, операция, обратная загрузке системы - останов - устроена в Linux как специальный уровень выполнения: 0 - если требуется выключить систему, и 6 - если требуется перезагрузка. Соответствующие каталоги rc0.d и rc6.d будут состоять почти сплошь из ссылок вида K*, но как минимум один сценарий, killall, будет запущен с параметром "start". Этот сценарий остановит все процессы, которые не были остановлены K-сценариями: программы пользователей, демоны, запущенные администратором вручную, и т.п.

Нечего и говорить, что отключение электропитания в разгар работы системы - операция очень рискованная. Даже в самом удачном случае при повторной загрузке rc.sysinit увидит, что файловые системы не былиразмонтированы, и станет проверять их целостность. В не самом удачном случае эта целостность будет нарушена: некоторые открытые на запись и не закрытые файлы окажутся в странном, недописанном состоянии, появятся индексные дескрипторы, не связанные ни с каким каталогом и т.п. Как правило, такие ошибки исправляются программой восстановленияфайловых систем fsck: с одной стороны, за счет дополнительных свойствфайловой системы (журнализация, сводящая вероятность порчи к минимуму, логически упорядоченная запись и т.п.), с другой - за счет некоторых предположений, которые делает сама утилита fsck. Однако надеяться на нее нельзя: очень редко, но бывают неразрешимые противоречия в лишенной цельности файловой системе, и тогда fsckобращается за помощью к администратору, требуя подтверждения действий (например, для удаления испорченного файла, который точно раньше был), или выполняя эти рискованные действия автоматически. В первом случае все время взаимодействия с администратором система будет работать в однопользовательском режиме, причем администратору предстоит разбираться с тем, что получилось; а во втором есть нешуточная вероятность того, что система испортится, а замечено это будет слишком поздно.



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

В экстренных случаях (например, когда при сбое электропитания демон, обслуживающий устройство бесперебойного снабжения, сообщает, что ресурсы на исходе) безопаснее все-таки быстро поостанавливать процессы, чем дожидаться отключения питания на работающей системе. Для этого можно послать всем процессам сначала TERM, а короткое время спустя - KILL. Для обработки таких ситуаций в inittab есть методы, начинающиеся со слова "power", а в /etc/rc.d - специальный сценарий rc.powerfail. На самый крайний случай существуют команды halt и reboot с ключом -f, однако их почти мгновенное действие практически эквивалентно внезапному отключению питания, и использовать их не рекомендуется.

Для останова или перезагрузки системы можно выполнять команды init 0 и init 6. Они вполне справятся с оповещением и остановкой активных программ, что займет минуту-две. А вот с пользователями, работающими в системе, все сложнее. Как правило, для завершения работы требуется хотя бы минут пять, а лучше - десять. Поэтому вежливые администраторы пользуются утилитой shutdown, которая запускается за несколько минут до времени перезагрузки, каждую минуту предупреждая пользователей о грядущем событии, после чего уже запускают init:

[root@localhost root]# shutdown -r +3 "Sorry, we need to reboot"

Broadcast message from root (ttyS0) (Sun Nov 28 14:05:41 2004):

Sorry, we need to reboot

The system is going DOWN to maintenance mode in 3 minutes!

. . .


Broadcast message from root (ttyS0) (Sun Nov 28 14:06:41 2004):

Sorry, we need to reboot

The system is going DOWN to maintenance mode in 2 minutes!

. . .


Broadcast message from root (ttyS0) (Sun Nov 28 14:07:41 2004):

Sorry, we need to reboot

The system is going DOWN to maintenance mode in 1 minute!

. . .


Broadcast message from root (ttyS0) (Sun Nov 28 14:08:41 2004):

Sorry, we need to reboot

The system is going down to maintenance mode NOW!

INIT: Switching to runlevel: 6

. . .

Пример 10.12. Использование shutdown (html, txt)

Остается заметить, что у shutdown есть обязательный параметр - время начала останова (в примере он равен "+3", то есть "через три минуты"), и необязательный - "-r" (reboot, перезагрузка) или "-h" (halt, останов). Без необязательных параметров выполняется переход на первый уровень выполнения, причем запускается стартовый командный интерпретатор суперпользователя, а после его завершения система вновь переходит на уровень выполнения по умолчанию (используется, например, для профилактических действий в системе). НажатиеCtrl+Alt+Del или кнопки выключения питания (в системах, где эта кнопка ничего не выключает, а лишь посылает соответствующий аппаратный сигнал) приводит к запуску именно shutdown -r или shutdown -h.


Представление устройства в системе


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

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

Большинству распознанных устройств, если они должны поддерживать операции чтения/записи или хотя бы управления (ioctl(), описанный ниже), соответствует файл-дырка в каталоге /dev или одном из его подкаталогов. В зависимости от того, выбрана ли в системе статическая или динамическая схема именования устройств, файлов-дырок в /dev может быть и очень много, и относительно мало. При статической схеме именования то, что ядро распознало внешнее устройство, никак не соотносится с тем, что в /dev имеется для этого устройства файл-дырка:

[root@localhost root]# cat /dev/sdg14

cat: /dev/sdg14: No such device or address

Пример 11.1. Обращение к несуществующему устройству (html, txt)

Здесь Мефодий попытался прочитать что-либо из устройства /dev/sdg14, что соответствует четырнадцатомуразделу SCSI-диска под номером 7. Такого диска в этой машине, конечно, нет, а файл-дырка для него заведен на всякий случай: вдруг появится? Поскольку появиться может любое из поддерживаемых Linux устройств, таких файлов "на всякий случай" в системе бывает и десять тысяч, и двадцать. Файл-дырка не занимает места на диске, однако использует индексный дескриптор, поэтому в корневой файловой системе, независимо от ее объема, должен быть изрядный запас индексных дескрипторов.

При динамической схеме именования применяется специальная виртуальная файловая система, которая либо полностью подменяет каталог /dev, либо располагается в другом каталоге (например, /sys), имеющем непохожую на /dev иерархическую структуру; в этом случае файлы-дырки в /dev заводит специальная служба. Этот способ гораздо удобнее и для человека, который запустил команду ls /dev, и для компьютера (в случае подключения внешних устройств, например, съемных жестких дисков, "на лету"). Однако он требует соблюдать дополнительную логику "привязки" найденного устройства к имени, иногда весьма запутанную из-за той же нечеткой идентификации. Поскольку происходить это должно в самый ответственный момент, при загрузке системы, динамическую схему именования используют с осторожностью.

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

Файлы-дырки и другие типы файлов


Кое-какие идеи динамического именования устройств присутствуют и в статической схеме. Так, файлы/dev/mouse или /dev/cdrom на самом деле представляют собой символьные ссылки на соответствующие файлы-дырки. Если тип мыши или лазерного привода изменится, достаточно изменить эти ссылки и перезапустить соответствующие службы:

[root@localhost root]# ls -l /dev/cdrom /dev/mouse

lrwxrwxrwx 1 root root 8 Nov 20 23:23 /dev/cdrom -> /dev/hdc

lrwxrwxrwx 1 root root 5 Nov 9 01:16 /dev/mouse -> psaux

[root@localhost root]# ls -lL /dev/cdrom /dev/mouse /dev/hda1 /dev/ur*

/dev/ze*


brw-r----- 1 root cdrom 22, 0 Jul 26 16:59 /dev/cdrom

brw-rw---- 1 root disk 3, 1 Jul 26 16:59 /dev/hda1

crw------- 1 root root 10, 1 Dec 2 11:58 /dev/mouse

crw-r--r-- 1 root root 1, 9 Nov 28 14:10 /dev/urandom

crw-rw-rw- 1 root root 1, 5 Jul 26 16:59 /dev/zero

Пример 11.2. Идентификация внешних устройств в /dev/ (html, txt)

Файл-дырка не имеет размера: сколько в него ни записывай, в файл на диске ничего не попадет. Вместо этогоядро передает все записанное драйверу, отвечающему за файл-дырку, а тот по-своему обрабатывает эти данные. Точно так же работает и чтение из файла-дырки: все запрашиваемые данные в нее подсовывает драйвер. Большинство драйверов - дисковые, звуковые, последовательных и параллельных портов и т.п. - обращаются за данными к какому-нибудь внешнему устройству или передают их ему. Но есть и такие, которые сами все "выдумывают": это и /dev/null, черная дыра, в которую что угодно можно записать, и все пропадет безвозвратно, и /dev/zero, из которого можно считать сколько угодно нулей (на запись оно ведет себя как /dev/null), и/dev/urandom, из которого можно считать сколько угодно относительно случайных байтов.

Изучив выдачу команды ls -lL (ключ "-L" заставляет ls выводить информацию не о символьной ссылке, а о файле, на который она указывает), Мефодий обнаружил, что та вместо размера файла-дырки (который равен нулю) выводит два числа. Первое из этих чисел называется старшим номером устройства (major device number), оно, упрощенно говоря, соответствует драйверу, отвечающему за устройство. Второе называется младшим номером устройства (minor device number), оно соответствует способу работы с устройством, а для дисковых носителей - разделу. В частности, из примера видно, что устройствами /dev/zero и /dev/urandom занимается один и тот же драйвер со старшим номером 1. При этом часть устройств (по преимуществу - дисковые) имеет тип "b", а другая часть - "c" (этот тип имеют, например, терминалы). Тип указан в атрибутах файла первым символом. Это блочные (block) устройства, обмен данными с которыми возможен только порциями (блоками) определенного размера, и символьные (character) устройства, запись и чтение с которых происходит побайтно. Блочные устройства, вдобавок, могут поддерживать команды прямого доступа вида "прочитать блок номер такой-то" или "записать данные на диск, начиная с такого-то блока".

Блочные и символьные устройства - полноправные объекты файловой системы, такие же, как файлы, каталоги и символьные ссылки. Есть еще два типа специальных файлов - каналы и сокетыКанал-файл (или fifo) называют еще именованным каналом (named pipe): это такой же объект системы, как и тот, что используется командной оболочкой для организации конвейера (его называют неименованным каналом), разница между ними в том, что у fifo есть имя, он зарегистрирован в файловой системе. Это - типичный файл-дырка, причем дырка двухсторонняя: любая программа может записать в канал (если позволяют права доступа) и любая программа может оттуда прочитать. Создать именованный канал можно с помощью команды mkfifo:

methody@localhost:~ $ mkfifo hole

methody@localhost:~ $ ( date >> hole & head -1 < hole ) 2> /dev/null

Птн Дек 3 15:11:05 MSK 2004

methody@localhost:~ $ ( cal >> hole & head -1 < hole ) 2> /dev/null

Декабря 2004

methody@localhost:~ $ rm hole

Пример 11.3. Использование именованного канала (html, txt)

Здесь важно, что утилита head показывает начало не "файла" hole, а именно последней записываемой порции данных, как и подобает трубе1).



Канал. Объект Linux, используемый в межпроцессном взаимодействии. Доступен в виде двух дескрипторов: один открыт на запись, другой - на чтение. Все данные, записываемые в первый дескриптор, немедленно можно прочитать из второго. Различают неименованный канал, уничтожаемый с закрытием обоих дескрипторов, иименованный канал (FIFO) - файл-дырку, создаваемый в файловой системе.

Что же касается сокетов, то это - более сложные объекты, предназначенные для связи двух процессов и передачи информации в обе стороны. Сокет можно представить в виде двух каналов (один "туда", другой "обратно"), однако стандартные файловые операции открытия/чтения/записи на нем не работают. Процесс, открывший сокет, считается сервером: он постоянно "слушает", нет ли в нем новых данных, а когда те появляются, считывает их, обрабатывает, и, возможно, записывает в сокет ответ. Процесс-клиент можетподключиться к сокету, обменяться информацией с процессом-сервером и отключиться. Точно так же можно передавать данные и по сети - в этом случае указывается не путь к сокету на файловой системе (так называемый unix domain socket), а сетевой адрес и порт удаленного компьютера (например internet socket, если подключаться с помощью сети Internet).


Драйверы устройств


Как уже говорилось в лекции 10, часть системы, отвечающая за взаимодействие с каким-нибудь внешним устройством и называемая "драйвер", в Linux либо входит в ядро, либо оформляется в виде модуля ядра и подгружается по необходимости. Следовательно, файл-дырка, обращение к которому приводило к "no such device or address", вполне может и заработать (в этом одна из причин огромного количества устройств в /dev). Гуревич наотрез отказался объяснять Мефодию, как добавить новый драйвер, до тех пор, пока тот не будет лучше разбираться в архитектуре компьютеров вообще и в аппаратной части IBM-совместимых компьютеров в частности. Поэтому все, что смог понять Мефодий, не имея таких знаний, сводилось к следующему. Во-первых, если существуют различия между тем, как по умолчанию загружает модули система и тем, как на самом деле это необходимо делать, различия должны быть описаны в файле /etc/modules.conf. Во-вторых, после изменения этого файла, добавления нового устройства, обновления самих модулей и т.п. следует запускать утилиту depmod, которая заново выстраивает непротиворечивую последовательность загрузки модулей. В-третьих, интересно (но в отсутствие знаний - малопознавательно) запускать утилиту lspci, которая показывает список устройств (распознаваемых по стандарту PCI), найденных на компьютере.

Работа с устройствами


Все файлы-дырки подчиняются одним и тем же правилам работы с файлами: их можно открывать для записи или чтения, записывать данные или считывать их стандартными средствами, а по окончании работы - закрывать. Открытие и закрытие файла (системные вызовы open() и close()) в командном интерпретаторе не представлены отдельной операцией, а выполняются автоматически при перенаправлении ввода (открытия на чтение) или вывода (на запись). Это позволяет работать и с устройствами, и с каналами, и с файлами совершенно одинаково, что активно используется в Linux программами-фильтрами. Каждый тип файлов имеет свою специфику, например, при записи на блочное устройство данные накапливаются ядром в специальном буфере размером в один блок, и только после заполнения буфера записываются. Если при закрытии файла буфер неполон, он все равно передается целиком: часть - данные, записанные пользователем, часть - данные, оставшиеся от предыдущейоперации записи). Это, конечно, не означает, что из файла, находящегося на блочном устройстве, легко по ошибке прочитать такой "мусор": длина файла известна, и ядро само следит за тем, чтобы программа не прочла лишнего.

Даже такие, казалось бы, простые устройства, как жесткие диски, поддерживают гораздо больше различных операций, чем просто чтение или запись. Пользователю, как минимум, может потребоваться узнать размер блока (для разных типов дисков он разный) или объем всего диска в блоках. Для многих устройств собственно передача данных - лишь итог замысловатого общения с управляющей программой или ядром. Скажем, для вывода оцифрованного звука на звуковую карту сначала необходимо настроить параметры звукогенератора: частоту, размер шаблона, количество каналов, формат передаваемых данных и многое другое. Для управленияустройствами существует системный вызов ioctl() (iputoutput control): устройство надо открыть, как файл, а затем использовать эту функцию. У каждого устройства - свой набор команд управления, поэтому в виде отдельной утилиты ioctl() не встречается, а используется неявно другими утилитами, специализирующимися на определенном типе устройств.


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


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

methody@localhost ~ $ who

methody tty1 Dec 3 16:02 (localhost)

shogun ttyS0 Dec 3 16:03 (localhost)

methody@localhost ~ $ ls -l /dev/tty1 /dev/tty2 /dev/ttyS0

crw--w---- 1 methody tty 4, 1 Дек 3 16:02 /dev/tty1

crw------- 1 root root 4, 2 Дек 3 15:51 /dev/tty2

crw--w---- 1 shogun tty 4, 64 Дек 3 16:03 /dev/ttyS0

methody@localhost:~ $ ls -l /usr/bin/write

-rwx--s--x 1 root tty 8708 Июн 25 14:00 /usr/bin/write



Пример 11.4. Кому принадлежат терминалы? (html, txt)

Права на владение терминалом передаются с помощью chown пользователю программой login после успешной регистрации в системе. Она же выставляет право записи на терминал членам группы tty. "Настоящих" пользователей в этой группе может и не быть, зато есть setGID-программы, например, write, которая умеет выводить сообщения сразу на все активные терминалы.

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

shogun@localhost ~ $ ls -l /dev | grep methody | wc 665 6649 41459

shogun@localhost ~ $ ls -lL /dev/{audio,cdrom,fd0,hda,kmem}

crw-rw---- 1 methody audio 14, 4 Июл 26 16:59 /dev/audio

brw-r----- 1 methody cdrom 22, 0 Июл 26 16:59 /dev/cdrom

brw-rw---- 1 methody floppy 2, 0 Июл 26 16:59 /dev/fd0

brw-rw---- 1 root disk 3, 0 Июл 26 16:59 /dev/hda

crw-r----- 1 root kmem 1, 2 Июл 26 16:59 /dev/kmem



Пример 11.5. Кому принадлежат устройства? (html, txt)

При этом для того чтобы обеспечить доступ и другим - псевдо- или настоящим - пользователям, такие устройства также принадлежат определенным группам с соответствующими правами. Практика "раздачи" устройств группам вообще очень удобна: даже если доступ к устройству имеет только суперпользователь, существует возможность написать setGID-программу, которая, не получая суперпользовательских прав, сможет до этого устройства добраться (а можно и просто включить опытного пользователя в такую группу).





Поделитесь с Вашими друзьями:
1   ...   26   27   28   29   30   31   32   33   ...   42


База данных защищена авторским правом ©vossta.ru 2019
обратиться к администрации

    Главная страница