77
Ответы на экзамен по СПО. 2016г Следует указывать под вопросом ссылки, откуда взята информация, и/или указывать после абзаца, является ли данный текст Вашими умозаключениями или предположениями. Список литературы: 1. https://vk.com/doc272919530_362328635?hash=6de29c546ad83d2c60&dl=b2065619e1436 d350b 2. http://maxim.int.ru/bookshelf/SolarisInternals.pdf 3. http://www.solarisinternals.com/wiki/index.php/Solaris_Internals_and_Performance_FAQ 4. http://minnie.tuhs.org/cgi-bin/utree.pl 5. https://archive.org/download/ATTUNIXSystemVRelease4Version2 6. http://randu.org/tutorials/threads/ 7. https://scoecomp.files.wordpress.com/2014/02/2003-unix-network-programming-vol-1-3rd-ed. pdf 8. Экзаменационные вопросы по системному программному обеспечению за второй семестр 2015/2016 учебного года. 1. История создания ( разработки ) основных ОС семейства UNIX. Принято считать, что исходным толчком к появлению ОС UNIX явилась работа Кена Томпсона по созданию компьютерной игры "Space Travel". Он делал это в 1969 году на компьютере Honeywell 635. В это же время Кен Томпсон, Деннис Ритчи и другие сотрудники Bell Labs предложили идею усовершенствованной файловой системы, прототип которой был реализован на компьютере General Electric 645. Однако компьютер GE-645, который был рассчитан на работу в режиме разделения времени и не обладал достаточной эффективностью, не годился для переноса Space Travel. Томпсон обнаружил, что появившийся к этому времени 18-разрядный компьютер PDP-7 с 4 килословами оперативной памяти и качественным графическим дисплеем вполне для этого подходит. Томпсон решил реализовать на PDP-7 разработанную ранее файловую систему. Дополнительным основанием для этого решения было то, что компания Bell Labs испытывала потребность в удобных и дешевых средствах подготовки и ведения документации. В скором времени на PDP-7 работала файловая система, в которой поддерживались: понятие inodes, подсистема управления процессами и памятью, обеспечивающая использование системы двумя пользователями в режиме разделения времени, простой командный интерпретатор и несколько утилит. Название придумал Брайан Керниган. Он предложил назвать эту двухпользовательскую систему UNICS (Uniplexed Information and Computing System). Название понравилось, поскольку, помимо прочего, оно напоминало об участии сотрудников Bell Labs в проекте Multics. В скором времени UNICS превратилось в UNIX. Первыми реальными пользователями UNIX стали сотрудники патентного отдела Bell Labs. Однако существовали некоторые проблемы, связанные с PDP-7. Во-первых, эта машина не принадлежала компьютерной группе (была только во временном пользовании). Во-вторых, возможности этого компьютера не удовлетворяли потребности исследователей. Поэтому в 1971 году был приобретен новый 16-разрядный компьютер фирмы Digital Equipment PDP-11/20, и на него была перенесена UNIX. Существовавший к этому времени вариант системы был написан на языке ассемблера, так что можно представить, что перенос был совсем не простым

О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

  • Upload
    others

  • View
    13

  • Download
    0

Embed Size (px)

Citation preview

Page 1: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

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

1. https://vk.com/doc272919530_362328635?hash=6de29c546ad83d2c60&dl=b2065619e1436d350b

2. http://maxim.int.ru/bookshelf/SolarisInternals.pdf 3. http://www.solarisinternals.com/wiki/index.php/Solaris_Internals_and_Performance_FAQ 4. http://minnie.tuhs.org/cgi-bin/utree.pl 5. https://archive.org/download/ATTUNIXSystemVRelease4Version2 6. http://randu.org/tutorials/threads/ 7. https://scoecomp.files.wordpress.com/2014/02/2003-unix-network-programming-vol-1-3rd-ed.

pdf 8.

Экзаменационные вопросы по системному программному обеспечению за второй семестр 2015/2016 учебного года. 1. История создания ( разработки ) основных ОС семейства UNIX.

Принято считать, что исходным толчком к появлению ОС UNIX явилась работа Кена Томпсона по созданию компьютерной игры "Space Travel". Он делал это в 1969 году на компьютере Honeywell 635. В это же время Кен Томпсон, Деннис Ритчи и другие сотрудники Bell Labs предложили идею усовершенствованной файловой системы, прототип которой был реализован на компьютере General Electric 645. Однако компьютер GE-645, который был рассчитан на работу в режиме разделения времени и не обладал достаточной эффективностью, не годился для переноса Space Travel. Томпсон обнаружил, что появившийся к этому времени 18-разрядный компьютер PDP-7 с 4 килословами оперативной памяти и качественным графическим дисплеем вполне для этого подходит. Томпсон решил реализовать на PDP-7 разработанную ранее файловую систему. Дополнительным основанием для этого решения было то, что компания Bell Labs испытывала потребность в удобных и дешевых средствах подготовки и ведения документации. В скором времени на PDP-7 работала файловая система, в которой поддерживались: понятие inodes, подсистема управления процессами и памятью, обеспечивающая использование системы двумя пользователями в режиме разделения времени, простой командный интерпретатор и несколько утилит. Название придумал Брайан Керниган. Он предложил назвать эту двухпользовательскую систему UNICS (Uniplexed Information and Computing System). Название понравилось, поскольку, помимо прочего, оно напоминало об участии сотрудников Bell Labs в проекте Multics. В скором времени UNICS превратилось в UNIX. Первыми реальными пользователями UNIX стали сотрудники патентного отдела Bell Labs. Однако существовали некоторые проблемы, связанные с PDP-7. Во-первых, эта машина не принадлежала компьютерной группе (была только во временном пользовании). Во-вторых, возможности этого компьютера не удовлетворяли потребности исследователей. Поэтому в 1971 году был приобретен новый 16-разрядный компьютер фирмы Digital Equipment PDP-11/20, и на него была перенесена UNIX. Существовавший к этому времени вариант системы был написан на языке ассемблера, так что можно представить, что перенос был совсем не простым

Page 2: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

делом. На PDP-11 система поддерживала большее число пользователей. Кроме того, была реализована утилита форматирования текстовых документов roff (тоже на языке ассемблера). Вторая редакция появилась в 1972 году. Наиболее существенным качеством "Второй редакции" было то, что система была переписана на языке Би ("B"). Язык и интерпретирующая система программирования были разработаны Кеном Томпсоном под влиянием существовавшего языка BCPL. Во второй редакции появились программные каналы ("pipes"). Появление варианта системы, написанного не на языке ассемблера, было заметным продвижением. Другие типы данных эмулировались библиотекой функций. Деннис Ритчи, который всегда увлекался языками программирования, решил устранить ограничения языка Би, добавив в язык систему типов. Так возник язык Си ("C"). В 1973 году Томпсон и Ритчи переписали систему на языке Си. К этому времени существовало около 25 установок ОС UNIX, и это была "Четвертая редакция". В июле 1974 года Томпсон и Ритчи опубликовали в журнале Communications of the ACM историческую статью. ОС UNIX заинтересовались в университетах. Этому способствовала политика компании Bell Labs, которая объявила о возможности бесплатного получения исходных текстов UNIX для использования в целях образования (нужно было платить только за носитель и документацию). Профессор Рейндфельдс был вынужден купить 32-разрядный компьютер Interdata 7/32, который был существенно дешевле, хотя и слабее по производительности. После нескольких попыток здравым образом дополнить "родную" операционную систему Interdata 7/32 OSMT/32 более развитыми средствами многопользовательского режима использования было принято решение попробовать перенести на эту 32-разрядную машину ОС UNIX V6. Очень замысловатым образом (напомним, что в австралийском университете не было доступного компьютера PDP-11) путем обмена магнитными лентами с университетом г. Беркли Ричард Миллер (канадец, работавший в Австралии) смог к январю 1977 года получить компилятор языка Си, который мог успешно компилировать собственный исходный текст на Interdata 7/32. Это позволило уже через месяц получить некоторый вариант ОС UNIX, работающий на этой же машине. Система Миллера представляла собой некий гибрид, основанный на ОС UNIX V6 и выполняемый "поверх" OSMT/32. Версия системы не включала собственных средств управления терминалами и обработки прерываний и поддерживала около восьми команд примитивного командного интерпретатора. Тем не менее, это была первая успешная (и быстро выполненная) попытка переноса ОС UNIX на компьютер с 32-разрядной архитектурой. Однако, к этому времени большой интерес к ОС UNIX стали проявлять коммерческие компании-производители компьютеров и программного обеспечения. Это объясняется тем, что с развитием технологии электронных схем резко упала стоимость производства новых однокристальных процессоров. Поэтому наличие по-настоящему мобильной операционной системы, перенос которой на новую аппаратную платформу не занимал слишком много времени и средств, позволяло экономно оснастить новые компьютеры качественным базовым программным обеспечением. Появились компании, специализирующиеся на переносе UNIX на новые платформы. Одной из первых была компания UniSoft Corporation, которая производила свою версию UNIX под названием UniPlus+. Microsoft Corporation совместно с Santa Cruz Operation (SCO) произвели вариант UNIX под названием XENIX. В результате к концу 70-х UNIX-подобные операционные системы были доступны на компьютерах, основанных на микропроцессорах Zilog, Intel, Motorola и т.д. Появились тысячи установок с ОС UNIX. В 1982 году USG выпустила за пределы Bell Labs свой первый вариант UNIX, получивший название UNIX System III. В этой системе сочетались лучшие качества UNIX Version 7, V/32 и других вариантов UNIX, имевших хождение в Bell Labs.

Page 3: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

2. Структура типовой ОС семейства UNIX (драйверы, ядро, процессы).

https://upload.wikimedia.org/wikipedia/commons/d/d0/OS-structure2.svg Монолитное ядро - большинство *nix, микроядро - Mach, Minix, Hurd, гибридное - Mac OS X. 3. Файловые системы UNIX (s5,ufs, типовая структура и назначение каталогов). Исходники SVR4 uts/i386/fs/{s5,ufs} Смешная шутка. На самом деле Вахалия. ( Ниже мини-мета-конспект главы 9. )

● s5fs ФС достаточно незатейливая, имплементированная простейшим образом, который

приходит в голову при мысли о структуре ФС.

Область загрузки содержит код для начальной загрузки ОС ( что в целом не

противоречит последовательности загрузки, описанной ниже ). Суперблок содержит атрибуты и метаданные ФС ( тип ФС, размер ФС, размер блока,

число свободных блоков и inode-ов, список свободных блоков и inode-ов ). Ядро читает данные из суперблока при монтировании и хранит их в памяти. Списки свободных inode не хранятся полностью; когда свободные кончаются, начинается поиск свободных и добавление их в список. Список свободных блоков хранится постоянно.

Список inode -- одномерный массив inode; имеет фиксированный размер, устанавливаемый при создании ФС.

Блоки данных: блоки, которые непосредственно хранят файлы, и блоки косвенной адресации , которые указывают на блоки, содержащие указатели на блоки с данными.

Каталоги.

Page 4: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

Аналогично привычному представления каталогов в качестве таблица ``inode -- имя’’. Одна запись 16 байт ( 2 байта -- inode, 14 байт -- имя ). Если inode == 0, то файл не существует ( тогда почему остаётся запись? ). Корень и его ``..’’ всегда имеют inode 2.

Индексные дескрипторы. Каждый файл ассоциирован с inode, который хранится на диске со списком inode-ов.

При открытии файла ( переход в каталог ) ядро копирует inode с диска в память. dinode ( on-disk-inode ) -- inode на диске, inode ( in-core inode ) -- inode в ОЗУ.

Структура поля di_mode ( 2 байта ): [type:4][suid:1][sgid:1][sticky:1][u:rwx:3][g:rwx:3][o:rwx:3]. Массив адресов блоков: с 0 по 9 блоки непосредственно хранят данные, остальные элементы ( с 10 по 12 ) указывают на блоки с одинарной, двойной и тройной адресацией ( напомню про блоки с косвенной адресацией ) соответственно возрастанию блока. Ядро не предоставляет пространнство для спарс-файлов, предоставляя блоки с косвенной адресацией, установленных в 0.

Page 5: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

Дескрипторы в ОЗУ. Дополнительные поля:

● vnode; ● ID устройства, на котором находится файл; ● номер inode; ● флаги синхронизации с кэшем; ● указатели на дескрипторы в списке свободных дескрипторов; ● указатели на дескрипторы в хэш-таблице; ● номер последнего прочитанного блока.

Файловый I/O происходит аналогично любому процессу I/O с участием vnode/vfs. Для блокировок s5fs использует эксклюзивные блокировки ( хз как работает ). Пример операции чтения.

1. s5read() преобразует первоначальное смещение в номер логического блока файла и смещение от его начала.

2. Копируется данные в пользовательское адресное пространство функцией uiomove(). Если необходимая страница отсутствует, генерируется ошибка страничной памяти и выполняется операция VOP_GETPAGE, которая в s5fs реализуется в функции s5getpage() ( ищет физический номер блока на диске, ищет vnode или просит свободную страницу и читает данные с диска ).

3. Снимается блокировка, увеличивается оффсет и завершается операция. При s5write данные пишутся не на диск, а в память и сбрасываются в память в

неопределённое для писателей время.

Возврат индексных дескрипторов. Когда счётчик inode становится нулю, вызывается операция VOP_INACTIVE, который

освободит inode. Но он не освобождается, а кэшируется и хранится в таблице хэширования до тех пор, пока не будет использован заново. inode является прикреплённым, если его файл часто используется. Тогда происходит кэширование его страниц,которые могут быть обнаружены через список страниц объекта vnode. Чёрт знает, как это работает.

Проблемы. 1. Целостность ФС зависит целиком от суперблока. 2. Не оптимальное расположение данных на диске. 3. Короткие имена файлов. 4. Размер блока.

● ufs

Копипаста с другой группы

Page 6: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

1. Файловая система UFS содержит загрузочный блок(boot-блок), суперблок, таблицу

индексных дескрипторов (i-node table), блоки группы цилиндров, блоки данных. Кроме этого, в Solaris в файловой системе хранятся списки управления доступом (ACL). Хранение списков ACL обеспечивают так называемые теневые индексные дескрипторы(shadow inodes).

2. Файловая система s5fs содержит загрузочный блок, суперблок, список индексных дескрипторов и блоки данных. /* описание для ufs и s5fs */ Загрузочный блок содержит код для начальной загрузки ( и

инициализации) ОС. Для хранения этой информации достаточно 1 раздела диска, но каждый доп. раздел на диске должен иметь эту область (пустую, касается ufs).

/* описание для ufs и s5fs */Суперблок содержит общую информацию о файловой системе как совокупности файлов на данном разделе жесткого диска, в частности, размер раздела UNIX, число свободных и занятых блоков и индексных дескрипторов и флаг целостности файловой системы. Этот флаг устанавливается при успешном завершении работы с файловой системой, например, при корректной остановке операционной системы. В случае, если компьютер выключили рубильником, не дождавшись корректной остановки системы, при следующем старте системы программа fsck автоматически начнет проверку дисков и выдаст сообщение "clean flag is not set in superblock". Копии суперблока многократно записываются в нескольких блоках внутри каждого раздела для пущей надежности. В файловой системе UFS записывается по одной копии суперблока на каждую группу цилиндров. Каждая копия суперблока имеет размер 8196 байт, и только одна копия суперблока используется при монтировании ФС. Если выяснится, что оригинал суперблока в начале раздела поврежден, будет использована копия суперблока.

Суперблок содержит метаданные применительно к ФС. В каждой ФС есть один суперблок, располагающийся в начале диска. Ядро читает данные из суперблока при

Page 7: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

монтировании файловой системы и хранит их в памяти до тех пор, пока система не будет размонтирована.

Суперблок содержит информацию: - размер ФС в блоках - размер списка индексных дескрипторов в блоках - кол-во свободных блоков и индексных дескрипторов - список свободных блоков - список свободных индексных дескрипторов

/* описание только для s5fs*/ Т.к. ФС может иметь большое кол-во свободных блоков и индексных дескрипторов,

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

Но это не прокатит для списка свободных блоков, т.к. нельзя определить незанятость блока, не проверив его содержимое. Т.о. ФС должна всегда поддерживать полный список всех свободных блоков на диске.

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

/* описание только для ufs*/ В UFS диск разбит на группы цилиндров. В каждой группе

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

Page 8: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

размера файловой системы. Для повышения эффективности файловая система UFS старается размещать i-узлы(они же файловые дескрипторы) и блоки данных в одной и той же группе цилиндров.

/* описание для ufs и s5fs*/ В файловых системах UFS современных систем таблица индексных дескрипторов распределена по диску, потому что каждая часть таблицы отвечает за часть диска.Размер индексного дескриптора фиксирован и составляет в Solaris в UFS 128 байт. Все современные системы UNIX используют 128-байтный индексный дескриптор, который вмещает больше информации и номер блока в нем занимает не 3 байта (как в прошлом), а 4. Поэтому адресовать можно весьма большие разделы. 28 байт в таком дескрипторе отводится под разные расширения, включая место для 32-разрядных идентификаторов владельца и группы файла, а также под 64-разрядные поля времен модификации. Введение 64-разрядных полей времени в UNIX вместо прежних 32-разрядных, нужно для того, чтобы избежать "проблемы 2031 года", т.к. именно в этом году перестанет хватать 32 байт для представления времени в системах UNIX. Разработчики обоснованно полагают, что до тех пор все существующие системы UNIXбудут переведены на 64-разрядную архитектуру. В индексном дескрипторе записаны:

- тип файла; - права доступа к файлу; - идентификатор владельца файла; - идентификатор группы файла; - время последней модификации файла; - время последнего доступа к файлу; - время последней модификации самого индексного дескриптора; - число повторных использований индексного дескриптора (т.е. случаев, когда файл был стерт и его индексный дескриптор был использован для хранения данных о другом файле); - длину файла в байтах (для файлов устройств это поле имеет смысл сочетания major и minor номера устройства, см. раздел "файлы устройств"); - идентификатор файловой системы, в которой расположен файл; - количество связей файла; - число блоков файла (требуется для поддержки работы с файлами, которые содержат большие области, заполненные символами с кодом "ноль", т.е. пустое пространство; такие файлы называются holey files – файлы с пустотами); - номер теневого индексного дескриптора (если требуется); - структура из 15 номеров блоков, описывающая размещение файла на диске; каждый номер блока занимает 4 байта.

Структура, описывающая физическое размещение файла на диске в UFS, представляет

собой последовательность из номеров блоков. Если файл имеет размер более двенадцати блоков (т.е. его длина больше 12 x 8192 = 98304 байт), то предпоследние три номера обозначают не номера блоков данных, а номера косвенных блоков (indirect blocks), в которых хранятся указатели на следующие блоки данных и, возможно, на следующие косвенные блоки. Первые двенадцать номеров блоков содержат просто номера блоков данных. Тринадцатый номер – это номер косвенного блока первого уровня. В блоке первого уровня содержится до

Page 9: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

2048 адресов блоков данных (речь идет о 8192-байтных блоках). Четырнадцатый номер блока содержит номер косвенного блока второго уровня. Косвенный блок второго уровня содержит 2048 номеров косвенных блоков первого уровня, таким образом, через косвенный блок второго уровня адресуется до 2048^2 блоков данных. В пятнадцатый номер блока записан номер косвенного блока третьего уровня. Косвенный блок третьего уровня содержит 2048 номеров косвенных блоков второго уровня, так что через косвенный блок третьего уровня адресуется до 2048^3 блоков данных. В s5fs дела с косвенными блоками обстоят так же. Важно помнить, что размер блока от 512 байт и увеличивается по степени с основанием 2(512, 1024 или 2048). Это число - единица дробления дискового пространства при размещении файла и объема данных для операций ввода-вывода. Физический номер блока - индекс в массиве блока.

/* описание только для s5fs*/ Список индексных дескрипторов является одномерным массивом индексных

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

КАТАЛОГИ.

Каталог в системе s5fs представляет собой спец.файл, содержащий список файлов и подкаталогов. В нем находятся фиксированные записи по 16 байт. В первых двух байтах - № индексного дескриптора, следующие 14 - для имени файла. Размер одной записи ограничивает общее кол-во файлов в разделе диска до 65535 и имя файла 14 символов. Если имя файла < 14 символов, то оно должно быть завершено символом NULL. Т.к. каталог тоже файл, он имеет собственный индексный дескриптор с полем, идентифицирующим его как каталог. Первые два элемента каталога “.”(сам каталог) и “..”(родительский). Если номер индексного дескриптора = 0, это означает, что файл, на который он указывает, больше не существует. Корневой каталог раздела и элемент “..” всегда имеет номер дескриптора = 2. При помощи этого значения ФС может идентифицировать корневой каталог.

В ufs имена файлов могут иметь длину до 255 символов (кодировка ASCII, по одному байту на символ).

Все файлы делятся на две группы - каталоги и прочие. Прочие файлы могут служить для различных целей (хранения данных и исполняемых программ, быть символическими ссылками, описывать устройства или средства взаимодействия процессов). Назначение же каталогов - быть хранителями имен входящих в них файлов, которым однозначно поставлены в соответствие идентификаторы inodes, хранящих метаданные этих файлов. То есть имя файла существует только в списке каталога и нигде более в системе. А создание файла -это не только заполнение относящейся к нему записи в индексной таблице и заполнение указанных в ней блоков данных, но и внесение записи вида “идентификатор - имя_файла” в область данных какого-либо каталога. /* (немного о теневом индексном дескрипторе)

Хранение списков ACL обеспечивают так называемые теневые индексные дескрипторы(shadow inodes). Теневые индексные дескрипторы (shadow i-nodes) содержат

Page 10: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

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

Если в отношении файла назначены расширенные права доступа (например, с помощью команды setfacl), то будет создан теневой индексный дескриптор для этого файла и в обычный индексный дескриптор этого файла будет записана ссылка на теневой индексный дескриптор. Теневой индексный дескриптор не имеет специального формата, он представляет собой точно такой же индексный дескриптор, как и обычный, но с указанием в поле типа дескриптора на то, что он – теневой. Расширенные права доступа хранятся в специальном файле, который создается в момент назначения таких прав. Теневой дескриптор указывает на этот специальный файл. В Solaris разрешено создавать не более 1024 записей в таком файле, следовательно, расширенные права доступа могут содержать не более 1024 специфических определений прав. Этого с избытком хватает для установки каких угодно специфических прав доступа. Каждая запись ACL занимает 12 байт, поэтому обычно эти записи не требуют много места на диске. Однако, при назначении специфических прав доступа большому числу объектов в файловой системе следует помнить о том, что для этого требуется дополнительный объем дисковой памяти.

Для назначения и просмотра расширенных прав доступа используются команды setfacl и getfacl.

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

Расширенные права доступа к файлам и каталогам устанавливаются командой setfacl. Они представляют собой ряд полей, разделенных двоеточиями:

entry_type:[uid|gid]:perms

Здесь entry_type – тип расширенного права доступа, uid и gid – идентификаторы пользователя и группы, соответственно, аperms – собственно назначаемые права доступа.

Маска задает максимальные права доступа для всех пользователей, за исключением

хозяина и групп. Установка маски представляет собой самый быстрый путь изменить фактические (эффективные) права доступа всех пользователей и групп. Например, маска r – показывает, что пользователи и группы не могут иметь больших прав, чем просто чтение, даже если им назначены права доступа на чтение и запись.

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

Page 11: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

Устанавливая права доступа по умолчанию для конкретных пользователей и групп, необходимо также установить права доступа по умолчанию для хозяина и группы файла, а также всех остальных, и маску ACL (эти четыре обязательных записи указаны выше по тексту – первыми в таблице 6.7).

Присвоение расширенных прав доступа осуществляется программой setfacl с ключом –s (set). Без этого ключа расширенные права доступа модифицируются, с ним – устанавливаются в точности такими, как указано в данной команде setfacl.

Например, для установки права на чтение и запись файла project07 для пользователей lena и petr надлежит выполнить команду

setfacl –m user:lena:rw-,user:petr:rw- project07 Ключ -m служит для добавления прав доступа, а не для их замены. Эффективные (т.е.

те, которые в самом деле будут применяться) права доступа пользователей lena и petr определяют не только их персональные права доступа к этому файлу, но и маска, которая показывает права доступа по умолчанию. Из персональных прав и маски выбираются наиболее строгие ограничения, поэтому, если в персональных правах доступа или в маске для файла project07 отсутствует право на запись, ни lena, ни petrне получат реальной возможности изменить файл project07.

Расширенные права доступа не показываются в выводе программы ls, но комаЩнда ls –l позволяет установить наличие расширенных прав доступа к файлу или каталогу. Если они назначены, то в первой колонке после стандартных прав доступа владельца, группы файла и остальных будет стоять знак "+" ("плюс"). Посмотреть, какие именно расширенные права доступа назначены, можно командой

getfacl имя_файла */ 4. Среда выполнения процесса (переменные, особенности их установки и использования). copy-paste by izoomko

Термин среда исполнения процесса включает экспортированные переменные shell, открытые файлы, текущую директорию, устанавливаемые по умолчанию права доступа при создания файла и т.д. Также, частью среды исполнения процесса могут считаться глобальные параметры настройки системы, влияющие на работу процесса, например, системное ограничение на максимальную длину имени файла или максимальный суммарный объем параметров exec(2).

Среда выполнения процесса формируется его родителем. Переменные среды процесса, значения которых задаются в командном интерпретаторе или в самом процессе с помощью функций libc (setenv(3C), getenv(3C)), а также наследуются порожденным процессом от родительского (char **environ, либо задается явно вызовами execve(2), execle(2)) и обычно хранятся в стеке.

Первоначально среда создается процессом init и затем изменяется с помощью login. Shell изменяет среду исполнения выполнением входного файла /etc/profile. Этот файл содержит все команды и установки переменных среды, которые системный администратор хочет исполнить для каждого входящего в систему. Если личная директория содержит .profile, shell читает команды из этого файла и модифицирует среду конкретного пользователя. Процессы пользователя далее так же могут изменять эту среду.

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

Page 12: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

правила — это идентификатор группы процессов и идентификатор родителя. Используя системный вызов setpgid(2), можно менять групповую принадлежность других процессов вашей терминальной сессии. Изменение идентификатора родительского процесса осуществляется косвенным путем: если родительский процесс завершается раньше, чем какой-то из его потомков, «осиротевший» процесс усыновляется процессом init (процессом с pid=1). Самый простой способ изменить остальные параметры среды исполнения другого процесса — это подключиться к этому процессу отладчиком и исполнить в контексте этого процесса функции или системные вызовы, изменяющие его среду. Вполне возможно, что такие изменения могут нарушить работу процесса.

Информация о среде исполнения содержится в двух местах: в пользовательской

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

чтобы получить доступ к ним, они должны быть объявлены как extern. Примеры таких переменных: errno и environ. В среду выполнения каждого процесса в системе UNIX включается текущий каталог. Текущий для процесса каталог является начальным каталогом, имя которого присоединяется ко всем именам путей поиска, которые не начинаются со слеша. Пользовательская область содержит информацию о среде исполнения процесса:

- Номер самого процесса и его процесса родителя - Группу процесса. Процесс входит в группу процессов. Сигнал может быть послан всем

процессам некоторой группы. - Ограничения процесса - максимально доступное время ЦП,максимальный размер

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

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

- Права доступа пользователя. - Информацию о файловой системе (? косвенно через u:u_cdir) - Действия, совершаемые при получении сигнала.

Стек содержит информацию об среде исполнения процесса:

- Параметры исполнения - Переменные командного интерпретатора shell

5. Основные концепции UNIX (фильтры, конвейеры, потоки в/в, перенаправление в/в). cppaste by izoomko Конвейер - конструкция, соединяющая команды в цепочку, перенаправляя дескриптор 1 левой команды на дескриптор 0 правой команды.

Фильтр читает информацию и сразу выводит результат, не обязательна обработка данных фильтром; программа, способная принимать данные у файла с дескриптором 0 и выводить данные в файл с дескриптором 1. Фильтр может работать со стандартным вводом, а также перенаправлять данные, которые он получает, на обработку для других команд.

Page 13: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

Потоки ввода - вывода: первые три зарезервированы (0-stdin, 1 - stdout, 2 - stderr), всего их 256. По умолчанию потоки ввода,вывода и ошибок ассоциированы с терминалом, т.е. любая программа, не использующая др. потоки, кроме стандартных, будет ожидать ввода с клавиатуры терминала. Весь вывод будет происходить на экран терминала.

Перенаправление В/В: - [N:-1]> S - направить вывод в файл S; - [N:-0]< S - направить ввод на файл;

- [N:-1]>> S - дозаписать вывод в файл; - [N:-0]<< [-]S - считать до символа S; (“-” - игнорирование табуляции ?)

- [N:-1]>& N - вывод перенаправить в файл с дескриптором N;

- [N:-0]<& N - на поток ввода перенаправляется файл с дескриптором N; - [N:-1]>& - закрытие потока вывода - [N:-0]<& - закрытие потока ввода

- [N:-0]<> S - открытие потока на чтение и на запись 6. Функции и роль операционной системы семейства UNIX. Нам нужны философы, историки, моралисты и экзорцисты. cppaste by izoomko: Операционная система (ОС) - система программ, реализующая интерфейс между аппаратурой ЭВМ и пользователями. Согласно своему назначению ОС выполняет два вида взаимосвязанных функций и рассматривается в двух аспектах: - управление распределением ресурсов вычислительной системы для обеспечения ее эффективной работы; ОС является менеджером ресурсов; - обеспечение пользователей набором средств для облегчения проектирования, программирования, отладки и сопровождения программ; ОС является виртуальной машиной, предоставляющей пользователю удобный интерфейс. Функцией ОС как менеджера ресурсов является распределение процессоров, памяти, устройств и данных между процессами, конкурирующими за эти ресурсы согласно выбранным критериям эффективности.

Page 14: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

ОС как виртуальная машина должна предоставлять некий интерфейс, избавляющий пользователя от непосредственной работы с аппаратурой и организации вычислительного процесса (в частности, распределения ресурсов и их защиты). Здесь можно говорить о двух уровнях (или видах) интерфейсов: - пользовательском, предназначенном для работы с готовыми приложениями; это все интерфейсные средства в диапазоне от командной строки до развитых графических оболочек; - программном, или интерфейсе прикладного программирования, представляющем собой средства для обращения к возможностям ОС при создании собственных приложений (фактически это системные функции, доступные разработчику). Конкретно UNIX: Unix задумывался как портабельная, мощная операционная система. Предполагалось наличие маленького, но удАленького ядра (ЧСХ, ничего не вышло. Даже Mach довольно большой) и клевой портабельности. В итоге, в 2016 году, это все довольно неплохо работает. Unix и его идеология ощутимо разрослись. Теперь все это работает под огромным количеством архитектур. Преимущественно Unix и Unix-like ОС используются как серверное ПО в силу здравого смысла. Кроме того существует кучка красноглазиков, добровольно использующих все прелести user-friendly (но все- таки максимально приятной) окружения. 7. Последовательность загрузки ОС. Файлы и сценарии запуска.

uts/i386/os/main.c svr4 www.ibm.com/developerworks/ru/library/l-linuxboot/ https://0xax.gitbooks.io/linux-insides/content/Booting/ https://www.opennet.ru/docs/RUS/unix/glava_74.html

При загрузке системы загружается код BIOS-a ( классический вариант ) из ПЗУ на мат. плате, которая в свою очередь тестирует и инициализирует аппаратуру ( Power-ON Self Test ). Если загрузка производится с жёсткого диска, BIOS читает MBR, проверяет его корректность ( MAGIC NUMBER в конце сектора ) и при успехе передает ему управление. MBR знает структуру таблицы разделов, так что ищет загрузочный раздел и передаёт управление загрузочному сектору, иначе возвращает управление в BIOS. Загрузка по сети предполагает использованием PXE ( код PXE в ПЗУ сетевой карты, данные по TFTP от BOOTP-сервера ).

В начале раздела расположен загрузчик операционной системы. Загрузчик осведомлён о расположении ядер всех доступных операционных систем ( настраивается в конфигурации загрузчика ); затем происходит загрузка ядра выбранной системы ( монтирование файловой системы загрузчика, поиск и распаковка образа программой в начале образа ). Ядро заново инитит всю аппаратуру и делает вещи, которые УЖЕ делал BIOS, затем начинается инициализация ядерных структур, монтирование корня, инициализация подсистемы памяти, порождение ядерных процессов ( pagedemon ), монтирование initrd ( пинукс ) и загрузка модулей.

После инициализации основных ядерных подсистем запускается процесс режима задачи init ( /sbin/init согласно FHS ). init берёт настройки инициализации userspace из /etc/inittab ( в нём указан уровень выполнения ( в ином случае уровень запрашивается через консоль ), сценарии запуска для каждого уровня выполнения и так далее ).

inittab состоит из строка вида: id:runlevels:action:process

Page 15: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

Где action -- команда из заранее определённого набора действий (

respawn -- перезапуск в случае завершения, sysinit -- действия до определения

уровня выполнения (в таком случае поле runlevels пустое? ) ); process --

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

Уровни выполнения: 0 -- остановка системы; 1 -- запуск в однопользовательном режиме; 2 -- запуск в многопользовательском режиме без поддержки сети; 3 -- запуск в многопользовательском режиме с поддержкой сети; 4 -- не используется; ( остался для сохранения совместимости? тогда для чего

использовался? ) 5 -- запуск в многопользовательском режиме с сетью и иксами; 6 -- перезагрузка.

TODO: rc init порождает процессы для каждого терминала ( из /etc/inittab ), которые вызывают setgrp и становятся лидерами сеансов своих терминалов; процесс вызывает getty, которая выводит приглашение и ждёт ввода.

8. Удалённая работа систем по протоколу SSH. Разделение одного подключения между несколькими сессиями работы. Возможности ограничения набора доступных команд. RFC: https://www.ietf.org/rfc/rfc4254.txt https://tools.ietf.org/html/rfc4253 Manual: http://www.openssh.com/manual.html iZoomko: а самого важного- то и нет, про что говорил С.А. на “консультации” Maar: А что он там говорил? iZoomko: ну не про screen и tmux) Про некоторое другое дерьмо вам нужен Multiplexing и ControlMaster https://www.freebsd.org/cgi/man.cgi?query=sshd&sektion=8&apropos=0&manpath=FreeBSD+10.3-RELEASE+and+Ports#AUTHORIZED_KEYS%09FILE_FORMAT > вам ?? izoomko: Сцуко, может быть все- таки мы будем писать, кому принадлежат реплики? http://rfc2.ru/4251.rfc :я вот вам еще паста В общем в SSH есть возможность при множественном подключении к серверу использовать только одно TCP соединение на все сессии с ним связанные(Multiplexing), таким образом мы вроде как будем быстрее передавать команды. Для этого в файле конфигурации SSH ( ~/.ssh/config) прописываем:

Host *

ControlMaster auto

ControlPath ~/.ssh/master-%r@%h:%p.socket

ControlPersist 30m

Звезда означает применение настроек ко всем подключениям можно указать имя для конкретного. При указании конкретного также указывается адрес и порт для коннекта.

Page 16: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

ControlPath : означает что в папке .ssh создастся запись основного подключения (создастся сокет) (то которое будет держать коннект для всех его потомков). спецификаторы %r@%h:%p указывают формат имени ам будет логи, аддрес, порт. По этой записи будут подключаться потомки мастер подключения. Так же за данный пункт отвечает ключ -S при создании подключения. %r - login name, @%h - host, %p - port.

ControlPersist 30m время которое будет существовать мастер. ControlMaster означает что будет создано мастер подключение автоматически, есть еще

вариант где он спрашивает как ты хочешь. Ключ -M сделает тоже самое при обычном подключении. После чего можно подключаться к серверу как обычно, ввод пароля потребуется при первичном подключении которое станет мастер подключением и будет еще существовать после выхода из SSH указанное время, все остальные коннекты пойдут через него и не будут требовать пароля. Все эти операции можно также осуществить через ключ -M. Каким образом происходит ограничение команд средствами ssh? Суть в root-доступе? 9. Различные типы файлов и особенности работы с ними.

● Обычный файл ● Каталог ● Символическая ссылка

Создание: symlink(2). Чтение: readlink(2). Если обращение происходит по символьной ссылке, то ядро будет интерпретировать

содержимое файла в качестве пути. ● Именованный канал

Создание mkfifo(3) ( в свою очередь вызывает mknod(2)). ● Сокет ( полнодуплексный канал ) ● Символьное устройство ● Блочное устройство

Я: там вот написано особенности работы с ними(если кто собирается всё же вопрос дополнить то интересно было бы узнать способ физического создания “именованного сокета” факт его существования описан в SSH) а так у всех стандартный набор операция унифицированы благодаря подсистеме ввода вывода, виртуальной ФС и тд. разве что у устройств на одну команду больше в которой можно не только читать и писать, а отправлять конкретные команды, реализованные в драйвере. С сокетом (если вы его таки создадите) как с потоком. 10. Структура файловой системы, суперблок, информационные узлы, фрагменты ufs. izoomko: см. копипаст с 4 вопроса. Там до жопы инфы *11. Виртуальная файловая система, таблицы и структуры. Изначально в UNIX была захардкожена лишь одна файловая система, что, в условиях бурно развивающихся технологии, не есть хорошо. В такой ситуации проблематично было взаимодействовать с внешними устройствами, с другими ОС или работать с сетевым диском. Тогда разработчики UNIX вдруг вспомнили про такую вещь как ООП и разработали очень красивый интерфейс, абстрагирующий файловую систему от конкретной реализации.

Page 17: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

Виртуальная файловая система(vfs) - это абстрактный класс(интерфейс) для любой файловой системы. typedef struct vfs {

struct vfs *vfs_next; /* next VFS in VFS list */ struct vfsops *vfs_op; /* operations on VFS */ struct vnode *vfs_vnodecovered; /* vnode mounted on */ u_long vfs_flag; /* flags */ u_long vfs_bsize; /* native block size */ int vfs_fstype; /* file system type index */ fsid_t vfs_fsid; /* file system id */ caddr_t vfs_data; /* private data */ dev_t vfs_dev; /* device of mounted VFS */ u_long vfs_bcount; /* I/O count (accounting) */ u_short vfs_nsubmounts; /* immediate sub-mount count */

} vfs_t; /* * Operations supported on virtual file system. */ typedef struct vfsops {

int (*vfs_mount)(); /* mount file system */ int (*vfs_unmount)(); /* unmount file system */ int (*vfs_root)(); /* get root vnode */ int (*vfs_statvfs)(); /* get file system statistics */ int (*vfs_sync)(); /* flush fs buffers */ int (*vfs_vget)(); /* get vnode from fid */ int (*vfs_mountroot)(); /* mount the root filesystem */ int (*vfs_swapvp)(); /* return vnode for swap */ int (*vfs_filler[8])(); /* for future expansion */

} vfsops_t; Виртуальный узел(vnode) - абстрактный интерфейс для файла. typedef struct vnode {

u_short v_flag; /* vnode flags (see below) */ u_short v_count; /* reference count */ struct vfs *v_vfsmountedhere; /* ptr to vfs mounted here */ struct vnodeops *v_op; /* vnode operations */ struct vfs *v_vfsp; /* ptr to containing VFS */ struct stdata *v_stream; /* associated stream */ struct page *v_pages; /* vnode pages list */ enum vtype v_type; /* vnode type */ dev_t v_rdev; /* device (VCHR, VBLK) */ caddr_t v_data; /* private data for fs */ struct filock *v_filocks; /* ptr to filock list */ long v_filler[8]; /* padding */

} vnode_t; /* * Operations on vnodes. */ typedef struct vnodeops {

int (*vop_open)(); int (*vop_close)();

Page 18: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

int (*vop_read)(); int (*vop_write)(); int (*vop_ioctl)(); int (*vop_setfl)(); int (*vop_getattr)(); int (*vop_setattr)(); int (*vop_access)(); int (*vop_lookup)(); int (*vop_create)(); int (*vop_remove)(); int (*vop_link)(); int (*vop_rename)(); int (*vop_mkdir)(); int (*vop_rmdir)(); int (*vop_readdir)(); int (*vop_symlink)(); int (*vop_readlink)(); int (*vop_fsync)(); void (*vop_inactive)(); int (*vop_fid)(); void (*vop_rwlock)(); void (*vop_rwunlock)(); int (*vop_seek)(); int (*vop_cmp)(); int (*vop_frlock)(); int (*vop_space)(); int (*vop_realvp)(); int (*vop_getpage)(); int (*vop_putpage)(); int (*vop_map)(); int (*vop_addmap)(); int (*vop_delmap)(); int (*vop_poll)(); int (*vop_dump)(); int (*vop_pathconf)(); int (*vop_allocstore)(); int (*vop_filler[31])();

} vnodeops_t; То есть когда процесс вызывает open(2), на самом деле система через функцию lookuppn находит соответствующий данному пути указатель на структуру vnode, которая содержит указатель на функцию open для конкретной файловой системы: Псевдокод: int open(path, flags, mode){

vnode *vp; lookuppn(..., path,&vp); return vp->v_op->vop_open(path, flags, mode);

} И так для каждой операции. Heil, OOP!

Page 19: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

12. Структура информационного узла (индексного дескриптора), ссылки на блоки данных. inode - индекс в массиве индексных дескрипторов и соответствующая ему структура данных inode для s5fs on-disk-inode следующий:

В общем- то оно везде примерно так и работает.

ДАЛЕЕ ЗНАТЬ НЕ ОБЯЗАТЕЛЬНО И ДАЖЕ ОПАСНО! В ZFS есть dnode, так он выглядит на диске:

Page 20: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

А в dnode с типом DMU_OT_ZNODE хранится znode typedef struct znode_phys {

uint64_t zp_atime[2]; uint64_t zp_mtime[2]; //content changed uint64_t zp_ctime[2]; //attr changed uint64_t zp_crtime[2]; uint64_t zp_gen; //transaction group number of the creation of this file uint64_t zp_mode; uint64_t zp_size; //size in bytes uint64_t zp_parent; //parent id uint64_t zp_links; uint64_t zp_xattr; uint64_t zp_rdev; //dev_t for devices uint64_t zp_flags; uint64_t zp_uid; uint64_t zp_gid; uint64_t zp_pad[4]; zfs_znode_acl_t zp_acl;

} znode_phys_t Очень похоже на то, что было, совсем немного добавилось полей.

Page 21: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

13. Файлы и каталоги. Атрибуты файлов и каталогов. Файл -- единица манипуляции файловой системы; интерфейс доступа к данным и

функциям устройства; абстракция, логическая единица хранения информации на файловой системе. Представляется структурой (izoomko: inode, но необязательно, inode может включаться в структуру большего размера типа znode в ZFS) ( КАКОЙ? )

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

Имя файла может состоять из любых символов, за исключением ‘\0’ ( строки нуль-терминированные ) и ‘/’ ( разделитель каталогов ). ‘.’ и ‘..’ ссылки на себя и на родительский каталог соответственно; на современных файловых системных данные ссылки не хранятся на диске, а являются (izoomko: псевдоссылками (K.O.), реализуемыми средствами ФС). izoomko: Линк на одну из ФС в составе школьникса. Нетрудно заметить, что там написано в комментарии к readdir. Кроме этого пока ничего не нашел за эту тему. Но в процессе. Современные ФС какие- то сложные http://lxr.free-electrons.com/source/fs/squashfs/dir.c?v=3.9#L122 Упоминание в nfs: http://lxr.free-electrons.com/source/fs/nfs/dir.c#L1241 http://lxr.free-electrons.com/source/fs/nfs/nfs4proc.c#L282 в UFS хранятся как есть Мм, либо оно хранится так, либо прям в inode. ЯННП чет пока

Для каталогов определён набор функций, позволяющих работать с ними. Стандартный интерфейс работы с файлами допустим ( ну ошибки не падают ), однако результатов это не даст.

Максимальная длина имени на zsf --- 256 ( man zsf, DESCRIPTION ). Атрибуты файла хранятся в inode; получить их можно с помощью вызова функций

семейства stat(2). Общие атрибуты, свойственные для большинства ФС.

1. Тип файла: обычный файл, каталог, символьная ссылка, именованный канал, сокет, блочное и символьные устройства.

2. Количество жёстких ссылок ( файл не удаляется, если присутствует хоть одна ссылка ). 3. Размер. 4. Устройство, на котором размещён файл. 5. inode. 6. GID, UID владельца. 7. mtime. ctime, atime.

13. Права ( некоторые файловые системы поддерживают ACL, с

соответствующими изменениями inode ). Атрибуты sticky, suid, sgid. Sticky -- флаг, который a) для каталогов позволяет процессу манипулировать каталогом

при условии совпадения UID ( вновь созданные каталоги имеют UID и GID создавшего

Page 22: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

процесса ), b) для исполняемых файлов указывает на необходимость кэширования программы ( кажется, в swap-области ).

SUID -- исполнение файла от имени владельца файла. SGID -- аналогично SUID; используется для mandatory locking для неисполняемых

файлов. izoomko: неточная инфа, по памяти

ACL. Можно хранить доступ либо в теневых inode (как в UFS2 сделано). Из корневого inode, который и соотносится с файлом, просто проставляется ссылка на другой inode etc.

По моим предположениям (я до конца не раздуплился в ZFS ACL), в ZFS есть специальный тип dnode для ACL`ов, так же списком все хранится, плюс еще в dnode кроме znode(extended inode) есть bonus buffer, где, кажется, тоже могут ACL размещаться. Все сказанное неточно с точностью до 50%. Верить мне на свой страх и риск. 14. Файловые дескрипторы. Таблица дескрипторов открытых файлов.

Дескриптор файла -- ссылка на объект открытого файла в таблице дескрипторов

открытый файлов процесса. Таблица дескрипторов ( массив struc file ) хранится в struct user ( u-области ). Объект

открытого файла описывается структурой struct file. ( пинуксовая реализация )

struct file { struct list_head f_list; /* список объектов file */ struct dentry *f_dentry; /* связанный объект dentry */ struct vfsmount *f_vfsmnt; /* связанная смонтированная файловая система */ struct file_operations *f_op; /* таблица файловых операций */ atomic_t f_count; /* счетчик ссылок на этот объект */ unsigned int f_flags; /* флаги, указанные при вызове функции open */ mode_t f_mode; /* режим доступа к файлу */ loff_t f_pos; /* смещение в файле (file pointer, offset) */ struct fown_struct f_owner; /* информация о владельце для обработки сигналов */ unsigned int f_uid; /* идентификатор пользователя владельца, UID */ unsigned int f_gid; /* идентификатор группы владельца, GID */ int f_error; /* код ошибки */ struct file_ra_state f_ra; /* состояние предварительного считывания */ unsigned long f_version; /* номер версии */ void *f_security; /* модуль безопасности */ void *private_data; /* привязка для драйвера терминала */ struct list_head f_ep_links; /* список ссылок eventpoll (опрос событий) */ spinlock_t f_ep_lock; /* блокировка eventpoll */ struct address_space *f_mapping; /* отображение в страничном кэше */ }; ( SVR4 ) typedef struct file {

struct file *f_next; /* pointer to next entry */ struct file *f_prev; /* pointer to previous entry */ ushort f_flag; cnt_t f_count; /* reference count */ struct vnode *f_vnode; /* pointer to vnode structure */ off_t f_offset; /* read/write character pointer */

Page 23: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

struct cred *f_cred; /* credentials of user who opened it */ struct aioreq *f_aiof; /* aio file list forward link*/ struct aioreq *f_aiob; /* aio file list backward link */ union {

off_t f_off; /* XENIX Support */ struct file *f_slnk; /* XENIX semaphore queue */ /* End XENIX Support */

} f_un; } file_t; fork создаёт копию файловых дескрипторов родительского процесса и передаёт их потомку; после возврата из fork предок и потомок разделяют между собой одинаковый набор открытых файлов. Maar: Вахалия пишет, что при fork-е предок и потомок разделяют объект файла и они видят изменения оффсетов, чего не происходит. Соответственно, возможна передача ссылки на объект открытого файла. Интерфейс зависит от системы: через вызов ioctl ( с помощью STREAMS ), через интерфейс сокетов и так далее.

● Это можно сделать с помощью системного вызова sendmsg и заголовка сообщения SCM_RIGHTS

15. Создание, монтирование и демонтирование файловых систем. В структуре vfs хранится указатель на массив операций, специфичных для файловой системы. /* * Operations supported on virtual file system. */ typedef struct vfsops {

int (*vfs_mount)(); /* mount file system */ int (*vfs_unmount)(); /* unmount file system */ int (*vfs_root)(); /* get root vnode */ int (*vfs_statvfs)(); /* get file system statistics */ int (*vfs_sync)(); /* flush fs buffers */ int (*vfs_vget)(); /* get vnode from fid */ int (*vfs_mountroot)(); /* mount the root filesystem */ int (*vfs_swapvp)(); /* return vnode for swap */ int (*vfs_filler[8])(); /* for future expansion */

} vfsops_t; Когда выполняется системный вызов mount(2) происходит следующее: По данному пути достается указатель на vnode. Далее проверяется v_vfsmountedhere, чтобы по данному пути ничего уже не было примонтировано. Затем выделяется память под новую структуру для монтируемой файловой системы, и выполняется VFS_INIT - специфичная функция для инициализации файловой системы. Затем выполняется VFS_MOUNT - тоже специфичная функция для монтирования ФС. ФС добавляется в общий список. При демонтировании ФС происходит поиск vnode, являющегося точкой монтирования ФС, либо блочного устройства, которое было примонтировано.( в таком случае указатель на vfs будет получен через функцию vfs_devsearch() ). Затем вызывается VFS_SYNC для сброса всех

Page 24: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

файловых операций, и VFS_UNMOUNT - специфичная функция для отмонтирования. Затем ФС убирается из общего списка и память освобождается. Fin. 16. Целостность файловой системы. Журнал ФС. Процедуры проверки и сопровождения.

Если происходит потеря данных при записи на диск, целостность системы не нарушается. При потере метаданных система теряет свою целостность.

Файловую систему можно считать целостной, если один блок данных принадлежит одному файлу, те есть изменение одного файла не приводит к изменению другого файла. Ядро посылает свои записи на диск для того, чтобы свести к минимуму опасность искажения файловой системы в случае системного сбоя. Например, когда ядро удаляет имя файла из родительского каталога, оно синхронно переписывает каталог на диск — перед тем, как уничтожить содержимое файла и освободить его индекс. Если система дала сбой до того, как произошло удаление содержимого файла, ущерб файловой системе будет нанесен минимальный: один из индексов будет иметь число связей, на 1 превышающее число записей в каталоге, которые ссылаются на этот индекс, но все остальные имена путей поиска файла останутся допустимыми. Если запись на диск не была сделана синхронно, точка входа в каталог на диске после системного сбоя может указывать на свободный (или переназначенный) индекс. Таким образом, число записей в каталоге на диске, которые ссылаются на индекс, превысило бы значение счетчика ссылок в индексе. В частности, если имя файла было именем последней связи файла, это имя указывало бы на не назначенный индекс.

Для того, чтобы свести к минимуму опасность искажения файловой системы в случае системного сбоя, ядро освобождает индексы и дисковые блоки также в особом порядке. При удалении содержимого файла и очистке его индекса можно сначала освободить блоки, содержащие данные файла, а можно освободить индекс и заново переписать его. Результат в обоих случаях, как правило, одинаковый, однако, если где-то в середине произойдет системный сбой, они будут различаться. Предположим, что ядро сначала освободило дисковые блоки, принадлежавшие файлу, и дало сбой. После перезагрузки системы индекс все еще содержит ссылки на дисковые блоки, занимаемые файлом прежде и ныне не хранящие относящуюся к файлу информацию. Ядру файл показался бы вполне удовлетворительным, но пользователь при обращении к файлу заметит искажение данных. Эти дисковые блоки к тому же могут быть переназначены другим файлам. Чтобы очистить файловую систему программой fsck, потребовались бы большие усилия. Однако, если система сначала переписала индекс на диск, а потом дала сбой, пользователь не заметит каких-либо искажений в файловой системе после перезагрузки. Информационные блоки, ранее принадлежавшие файлу, станут недоступны для системы, но каких-нибудь явных изменений при этом пользователи не увидят. Программе fsck так же было бы проще забрать назад освободившиеся после удаления связи дисковые блоки, нежели производить очистку, необходимую в первом из рассматриваемых случаев.

Технология журналирования(logging или journaling) позволяет избавиться от ограничений традиционных систем. А именно:

- производительность - восстановление после сбоя

производится с помощью команды sfck, которая просматривает всю файловую систему, ища проблемы и разрешая их по мере возможностей; при больших объемах дисков эта процедура

Page 25: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

может занять много времени, т.к. программа осуществляет проверку и перестройку диска целиком => задержки до того момента, как машина перегрузится и снова станет доступной

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

- размер (более подробно про эти ограничения - Вахалия гл.11.2 со стр 494)

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

Это описание упрощенное, рассмотрим их реализацию более подробно. Разработка файловых систем приводит к ряду вопросов.

- какую информацию вносить? можно вести записи всех изменений, можно записывать только модификации метаданных

- операции или значения? можно записывать либо отдельные операции, либо результаты операций

- дополнение или замещение? Расширенные журнальные файловые системы поддерживают традиционные дисковые структуры (индексные дескрипторы, суперблоки), журнал в качестве вспомогательного средства; в структурированных журнальных ФС журнал - представление файловой системы на диске

- повторное или обратное заполнение? 2 типа журналов: с возможностью отмены изменений(redo-only, запись только модифицированных данных) и с разрешением отмены и восстановления (undo-only, сохраняются и старые, и новые значения данных).

- хранить ли мусор? либо журналы бесконечной длины (устаревшие части журнала - на третичные носители), либо конечного размера(требуется хранение устаревших частей журнала, интерпретируемых как логически замкнутый цикличный файл).

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

- как получать данные из журнала? требуется эффективный механизм индексирования с целью нахождения произвольных блоков файла журналов

Вахалия 11.5(про журналы в структурированных ФС) и 11.6(журнал в BSD4.4) для полноты картины.

Утилита fsck умеет производить диагностику ФС, находить нарушения целостности и восстанавливать ее, если это возможно. fsck использует прямой доступ к дисковому драйверу для доступа к ФС. ( см 11.2.4)

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

Page 26: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

подтверждение на каждое действие по ликвидации повреждений. Необходимо отметить, что почти всегда при ликвидации повреждений файловой системы происходит частичная потеря информации. Количество потерянных данных и серьезность потери может быть определена по выдаваемой диагностике. В случае положительного ответа (yes) повреждение ликвидируется. Если у пользователя, запустившего fsck, нет прав на запись, считается, что ответ на все вопросы отрицательный (no). Если файловая_система не указана, проверяются файловые системы из списка, хранящегося в файле /etc/checklist. Выявляются следующие нарушения целостности ФС:

1. На блок имеется более одной ссылки из описателей файлов и/или списка свободных блоков.

2. Блок, на который ссылается описатель файла или список свободных блоков, находится за пределами файловой системы.

3. Некорректные счетчики числа ссылок. 4. Проверка размеров: некорректное число блоков;размер каталога не кратен 16. 5. Некорректный формат описателя файла 6. Наличие неучтенных блоков. 7. Проверка каталогов:элемент каталога указывает на свободный описатель

файла;недопустимый номер описателя файла. 8. Проверка суперблока:более 65536 описателей файлов;под описатели файлов выделено

больше блоков, чем есть в файловой системе. 9. Некорректный формат списка свободных блоков. 10. Некорректные значения счетчиков свободных блоков и/или свободных описателей

файлов. Непустые файлы, на которые нет ссылок, с согласия пользователя (а каталоги -

обязательно) перемещаются в каталог lost+found. Если не указана опция -n, пустые файлы и каталоги удаляются. Каталог lost+found должен существовать, располагаться в корне проверяемой файловой системы и иметь свободные места для внесения новых элементов. Чтобы удовлетворить всем требованиям, надо перед выполнением fsck создать каталог /lost+found, записать в него несколько файлов, а потом удалить их.

Утилита dfsck позволяет одновременно проверять целостность двух групп файловых систем, расположенных на двух устройствах с независимым доступом. Набор_опций передается утилите fsck для обработки соответствующей группы файловых_систем. Группы разделяются символом -. Перед каждым сообщением dfsck печатает имя файловой системы, к которой сообщение относится. Свои ответы на вопрос утилиты dfsck пользователь должен начинать с 1 или 2, что означает номер группы, к которой относится ответ. Утилиту dfsck нельзя использовать для проверки целостности корневой файловой системы.

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

Page 27: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

17. Состояния процесса и переходы между ними.

18. Размещение ядра. Прерывания и исключения. izoomko: Загрузчик распаковывает ядро в память, настраивает таблицы виртуальных адресов для него, после чего запускает. С этого момента ядро работает до выключения машины и находится на постоянных физических адресах. Для каждого процесса ядро размещает себя в его таблице виртуальных адресов (разумеется, в PTE для этих страниц supervisor = 1, т.е. доступ только из привелегированного режима)

( ЗАЧЕМ ? ) http://thegeekdiary.com/solaris-10-boot-process-x86x64/ далее копипаст: Прерывания Система отвечает за обработку всех прерываний, поступили ли они от аппаратуры (например, от таймера или от периферийных устройств), от программ (в связи с выполнением инструкций, вызывающих возникновение «программных прерываний») или явились результатом особых

Page 28: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

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

1) Сохраняет текущий регистровый контекст выполняющегося процесса и создает в стеке (помещает в стек) новый контекстный уровень.

2) Устанавливает "источник" прерывания, идентифицируя тип прерывания (например, прерывание по таймеру или от диска) и номер устройства, вызвавшего прерывание (например, если прерывание вызвано дисковым запоминающим устройством). При возникновении прерывания система получает от машины число, которое использует в качестве смещения в таблице векторов прерывания. Содержимое векторов прерывания в разных машинах различно, но, как правило, в них хранится адрес программы обработки прерывания, соответствующей источнику прерывания, и указывается путь поиска параметра для программы.

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

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

Исключения Связаны с возникновением событий в окружении пользователя. Такие операции, как division by zero, попытки обращения к виртуальным страницам со сброшенным битом корректности, недопустимая в режиме задачи команда. Можно разделить на:

● Нарушения: могут быть скорректированы в рантайме и программа может продолжить без каких- либо проблем div by zero bound rage exception invalid opcode page fault etc.

● Ловушки: инструкции INTO (проверка на переполнение), INT3 (breakpoint), BOUND (проверка границ массива) debug exception breakpoint single-step

Page 29: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

etc. ● Авария: неразрешимые ошибки, которые нельзя починить

Double fault - например, когда запускается обработчик page fault, который находится на выгруженной странице. Page faut + page fault => ABORT В UNIX обработка исключений и прерываний происходит абсолютно идентично. 19. Адресное пространство процесса. Контекст процесса , контекст потока. Переключение контекста. https://new.vk.com/doc-89761001_403104439?dl=3ca35e38e7ff44041b

copypaste by izoomko Адресное пространство процесса представляет собой набор адресов памяти, к которым тот

имеет доступ и на которые может ссылаться. Каждый процесс имеет свое собственное пространство, однако ядро обращается к

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

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

Каждый процесс имеет четко определенный контекст, включающий всю информацию, необходимую для его описания. Ниже перечислены компоненты контекста:

● Адресное пространство задачи. Обычно делится на несколько составляющих: текст программы (выполняемый код), данные, куча, стек задачи, совместно используемые области памяти и т. д.

● Управляющая информация. Ядро использует для поддержки управляющей информации о процессе две основные структуры данных: область u и структуру proc. Каждый процесс также обладает собственным стеком ядра и картами трансляции адресов.

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

● Переменные окружения. Это набор строк в форме: переменная=значение Переменные окружения наследуются от родительского процесса. Во многих

вариантах UNIX такие строки хранятся в вершине стека. Стандартные

Page 30: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

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

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

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

состоянии системы, в том числе о текущем и предыдущем режимах выполнения, текущем и предыдущем уровнях приоритетов прерываний, а также биты переполнения и переноса.

o Регистры управления памятью, в которых отображаются таблицы трансляции адресов процесса.

o Регистры сопроцессора. Машинные регистры содержат аппаратный контекст текущего выполняемого процесса.

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

Переключение контекста: Вахалия(стр. 61): Когда текущий процесс уступает процессорное время другому процессу

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

Вахалия(стр.187): На самом низком уровне планировщик заставляет процессор производить переключения от одного процесса к другому. Это действие называется переключением контекста. Ядро системы сохраняет аппаратный контекст текущего выполняющегося процесса в блоке управления процессором(process control block), который обычно является частью области u. Контекст представляет собой “моментальный снимок” текущих значений регистров общего назначения, регистров управления памятью и других специальных регистров. После завершения процедуры сохранения ядро системы загружает аппаратные регистры с контекстом следующего процесса, готовящегося к выполнению (контекст загружается из блока PCB). Это действие приводит к тому, что CPU начинает выполнение нового процесса.

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

Page 31: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

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

ПЕРЕКЛЮЧЕНИЕ КОНТЕКСТА (СТР 45) Ресурсы, включающие адресное пространство, открытые файлы, полномочия, квоты и т.д. используются всеми нитями процесса совместно. Каждая нить, кроме того, обладает собственными объектами, такими как указатель команд, стек и контекст регистров. 20. Атрибуты, области (сегменты) и структуры данных процесса. Атрибуты процесса

● Идентификатор процесса (PID) Каждый процесс имеет уникальный идентификатор PID, позволяющий ядру системы

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

● Идентификатор родительского процесса (PPID) Идентификатор процесса, породившего данный процесс. Все процессы в системе, кроме

системных процессов и процесса init, являющегося прародителем остальных процессов, порождены одним из существующих или существовавших ранее процессов.

● Поправка приоритета (NI) Относительный приоритет процесса, учитываемый планировщиком при определении

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

● Терминальная линия (TTY) Терминал или псевдотерминал, связанный с процессом. Процессы-демоны не связаны с

терминалом. Реальный (UID) и эффективный (EUID) идентификаторы пользователя

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

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

● Реальный (GID) и эффективный (EGID) идентификаторы группы

Page 32: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

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

stack - стек для локальных переменных функций (автоматических переменных). Этот

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

data - сегмент, в который склеены сегменты статических данных DATA и BSS, загруженные из файла. Этот сегмент также может изменять свой размер, но делать это надо явно - системными вызовами sbrk или brk. В частности, функция malloc() для размещения динамически отводимых данных увеличивает размер этого сегмента.

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

имеющихся у каждого процесса: области u и структуры proc. Таблица процессов – массив фиксированного размера в ядре, состоящий из структур proc.

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

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

Основные поля области u: ➢ Блок управления процессом используется для хранения аппаратного контекста в то

время, когда процесс не выполняется. ➢ Указатель на структуру proc для этого процесса. ➢ Реальные и эффективные uid и guid. ➢ Входные аргументы и возвращаемые значения (или коды ошибок) от текущего сисколв ➢ Обработчики сигналов и информация, связанная с ними. ➢ Информация из заголовка программы, в том числе размеры текста, данных и стека, а

также информация по управлению памятью. ➢ Таблица дескрипторов открытых файлов. ➢ Указатель на vnode. (- объекты файловой системы).

Page 33: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

➢ Статистика использования процессора, информация о профиле процесса, дисковых квотах и ресурсах.

➢ Во многих реализациях также стек ядра Основные поля структуры proc охватывают:

➢ идентификацию: каждый процесс обладает уникальным идентификатором процесса и относится к определенной группе процессов. В современных версиях системы каждому процессу также присваивается идентификатор сеанса.

➢ расположение карты адресов ядра для области u данного процесса. ➢ текущее состояние данного процесса ➢ предыдущий и следующий указатели, связывающие процесс с очередью планировщика

(или очередью приостановленных процессов, если данный был заблокирован) ➢ канал сна для заблокированных процессов (см раздел 7.2.3) ➢ приоритеты планирования задач и связанную информацию (см главу 5) ➢ Информация об обработке сигналов: в маске игнорируемых, блокируемых,

передаваемых и обрабатываемых сигналов (см главу 4) ➢ Информацию по управлению памятью ➢ Указатели, связывающие эту структуру со списками активных, свободных или

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

21. Группы и сеансы. Управляющий терминал. Функция isatty(3). Утилита getty. Общие положения:

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

Каждый процесс относится к определенной группе процессов, которая идентифицируется через через идентификатор группы процессов. Этот механизм используется ядром для проведения некоторых действий стразу над всеми процессами tгруппы. Лидер группы - это процесс, имеющий PID, совпадающий с идентификатором группы процессов.

Управляющий терминал. Любой процесс может обладать управляющим терминалом. Чаще всего это терминал входа в систему, от которого процесс был создан. Все процессы одной группы разделяют между собой один и тот же управляющий терминал. С управляющим терминалом каждого процесса связан связан специальный файл /dev/tty. Драйвер устройства связанный с этим файлом, перенаправляет все запросы на соответствующий терминал. То есть если два процесса относятся к различным сеансам входа в систему и они оба откроют /dev/tty, то результатом станет доступ у разным терминалам.

Управляющая группа. Каждый терминал ассоциируется с группой процессов. Такая группа - управляющая группа терминала - идентифицируется при помощи поля t_pgrp структуры tty этого терминала (драйвер содержит отдельную структуру для каждого терминала). Сигналы, вырабатываемые при вводе с клавиатуры, такие как SIGINT или SIGQUIT, посылаются всем процессам управляющей группы терминала.

Управление заданиями (реализовано в 4BSD и SVR4). Механизм позволяет приостановить и возобновить работу группы процессов, а также управлять ее доступом к терминалу. Драйвер терминала обеспечивает дополнительное управление, посредством

Page 34: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

которого процессы, не входящие в управляющую группу терминала, защищены от чтения и записи в терминала. Далее в Вахалии со страницы 170 (раздел 4.9.2) начинается описание реализации технологий в SVR3, 4.3BSD, имеющих собственные недостатки и избавление от ограничений данных моделей в SVR4. Так что приведем описание только последней модели.

Сеансы и группы процессов. Архитектура сеансов ОС SVR4:

Каждый процесс относится как к определенному сеансу, так и к группе. Точно так же

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

Группа процессов обладает основными чертами групп в 4.3BSD и обычно представляет собой задание внутри сеанса входа в систему (стр 179). Таким образом, в одном сеансе входа в систему одновременно могут функционировать несколько групп процессов. Одна из таких групп является текущей и обладает неограниченным доступом к терминалу ( = упр группа терминала).

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

Page 35: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

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

Управляющий терминал /dev/tty - псевдоним управляющего терминала. Драйвер разрешает любык вызовы в

/dev/tty посредством просмотра указателя на сеанс в структуре proc и, используя его, получает дескриптор vnode упр терминала.

Если драйвер терминала обнаружит разорванное соединение, то он пошлет сигнал

SUGHUP только лидеру сеанса. Лидер сеанса при таком подходе является доверенным лицом и ожидается, что он произведет корректные действия при потере УТ. Доайвер также пошлет SUGSTP текущей группе, если она не является группой лидера сеанса. Управляющий терминал остается за закрепленным сеансом, это дает возможность лидеру сеанса попытаться заново соединится с терминалом после восстановления соединения. Лидер сеанса может отключится от отдного текущего терминала и открыть новый. Осуществляется посредством установки объекста vnode сеанса на указатель vnode нового терминала.

Когда лидер сеанса заканчивает свою работу, он завершает и сеанс входа в систему. Управляющий терминал освобождается при помощи установки указателя vnode сеанса в null. В результате ни один процесс не сможет иметь доступа к терминалу посредством /dev/tty (но при непосредственном открытии файла устройства терминала могут). Процессы текущей группы получают сигнал SUGHUP. Все прямые потомки существующего процесса будут унаследованы init.

Функция isatty(3). - тестирует терминальное устройство; Функция isatty(int fildes) тестирует,

является ли fildes открытым файлов дескриптором, который ассоциирован с

Page 36: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

терминалом. В данном случае функция возвращает 1, иначе 0 и устанавливает errno в EBADF(fildes не является корректным дескриптором) или ENOTTY (fildes не ассоциирован с терминалом).

Утилита getty. - устанавливает тип терминала, режимы, скорость и line discipline. getty - это

символьная ссылка на /usr/lib/saf/ttymon (нужно для совместимости). Может быть выполнен только супер юзером. Данная утилита выводит приглашение на вход в систему и ждет ввода. Когда пользователь вводит свое регистрационное имя, программа запускает команду входа в систему (login), которая запрашивает и верифицирует пароль. getty пытается адаптировать систему к скорости терминала, используя параметры и аргументы, заданные в командной строке.

22. Взаимодействие с операционной системой через вызовы системных функций.

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

Интерфейс системных вызовов (2.4.1. стр. 73) Программный интерфейс ОС определялся набором системных вызовов,

предоставляемых ядром пользовательским процессам. Стандартная библиотека С, подключаемая по умолчанию ко всем программам пользователя, содержит процедуру встраивания для каждого системного вызова. Когда программа делает системный вызов, вызывается и соответствующая ему процедура встраивания. Она передает номер системного вызова (идентифицирующего каждый вызов ядра) в пользовательский стек и затем вызывает специальную функцию системного прерывания. Имя инструкции зависит от конкретной машины (например, это - syscall для MIPS R3000, chmk для VАХ-11 или trар для Motorola 680х0). Функция этой инструкции заключается в изменении режима выполнения на режим ядра и передачи управления обработчику системного вызова, определенному по таблице диспетчеризации. Этот обработчик, обычно имеющий название syscall(), является точкой старта обработки любого системного вызова ядром.

Системные вызовы выполняются в режиме ядра, но в контексте процесса. Следовательно, они имеют возможность доступа к адресному пространству и области u вызтвающего процесса. С другой стороны, они могут обращаться и к стеку ядра этого процесса. Обработчик syscall() копирует входные аргументы системного вызова из пользовательского стека в область u, а также сохраняет аппаратный контекст процесса в стеке ядра. Затем он использует номер системного вызова для доступа о его вектору (обычно называемому sysent[]), чтобы определить какую именно функцию необходимо вызвать для обработки поступившего системного вызова. После завершения работы необходимой функции обработчик syscall() устанавливает возвращенные ею значения или код ошибки в соответствующие регистры, восстанавливает аппаратный контекст процесса, возвращает

Page 37: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

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

может "заснуть", дожидаясь некоторого события (например, нажатия кнопки на клавиатуре). В это время ядро передаст управление другому процессу. Когда наш процесс будет "разбужен" (событие произошло) - он продолжит выполнение шагов системного вызова. 23. Описание управления адресным пространством процесса. Функция brk(2). Ссылка на brk source

Каждый процесс в многозадачной ОС выполняется в собственной “песочнице”. Эта песочница представляет собой виртуальное адресное пространство, которое в 32-битном защищенном режиме всегда имеет размер равный 4 гигабайтам. Соответствие между виртуальным пространством и физической памятью описывается с помощью таблицы страниц (page table). Ядро создает и заполняет таблицы, а процессор обращается к ним при необходимости осуществить трансляцию адреса. Каждый процесс работает со своим набором таблиц. Есть один важный момент — концепция виртуальной адресации распространяется на все выполняемое ПО,включая и само ядро. По этой причине для него резервируется часть виртуального адресного пространства (т.н. kernel space).

Page 38: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

1) В верхней части user mode space расположен стековый сегмент. Большинство языков

программирования используют его для хранения локальных переменных и аргументов, переданных в функцию. Вызов функции или метода приводит к помещению в стек т.н.стекового фрейма. Когда функция возвращает управление, стековый фрейм уничтожается. Стек устроен достаточно просто — данные обрабатываются в соответствии с принципом «последним пришёл — первым обслужен» (LIFO). По этой причине, для отслеживания содержания стека не нужно сложных управляющих структур – достаточно всего лишь указателя на верхушку стека. Добавление данных в стек и их удаление – быстрая и четко определенная операция. Более того, многократное использование одних и тех же областей стекового сегмента приводит к тому, что они, как правило, находятся в кеше процессора, что еще более ускоряет доступ. Каждый тред в рамках процесса работает с собственным стеком. Если пространство, отведенное под стековый сегмент, не может вместить в себя добавляемые данные, будет сгенерирован page fault, который в Linux обрабатывается функцией expand_stack(). Она, в свою очередь, вызовет другую функцию — acct_stack_growth(), которая отвечает за проверку возможности увеличить стековый сегмент. Если размер стекового сегмента

Page 39: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

меньше значения константы RLIMIT_STACK (обычно 8 МБ), то он наращивается, и программа продолжает выполняться как ни в чем не бывало. Это стандартный механизм, посредством которого размер стекового сегмента увеличивается в соответствии с потребностями. Однако, если достигнут максимально разрешённый размер стекового сегмента, то происходит переполнение стека (stack overflow), и программе посылается сигнал Segmentation Fault. Стековый сегмент может увеличиваться при необходимости, но никогда не уменьшается, даже если сама стековая структура, содержащаяся в нем, становиться меньше.

2) Под стеком располагается сегмент для memory mapping. Ядро использует этот сегмент для мэппирования (отображания в память) содержимого файлов. Любое приложение может воспользоваться данным функционалом посредством системного вызова mmap(). Отображение файлов в память – удобный и высокопроизводительный метод файлового ввода / вывода, и он используется, например, для загрузки динамических библиотек. Существует возможность осуществить анонимное отображение в память (anonymous memory mapping), в результате чего получим область, в которую не отображен никакой файл, и которая вместо этого используется для размещения разного рода данных, с которыми работает программа. Если в Linux запросить выделение большого блока памяти с помощью malloc(), то вместо того, чтобы выделить память в куче, стандартная библиотека C задействует механизм анонимного отображения. Слово «большой», в данном случае, означает величину в байтах большую, чем значение константы MMAP_THRESHOLD. По умолчанию, это величина равна 128 кБ, и может контролироваться через вызов mallopt().

3) Подобно стеку, куча используется для выделения памяти во время выполнения программы. В отличие от стека, память, выделенная в куче, сохранится после того, как функция, вызвавшая выделение этой памяти, завершится. Если текущий размер кучи позволяет выделить запрошенный объем памяти, то выделение может быть осуществлено средствами одной лишь среды выполнения, без привлечения ядра. В противном случае, функция malloc() задействует системный вызов brk() для необходимого увеличения кучи /*Время, затрачиваемое на каждый запрос по выделению памяти в куче, может разительно отличаться. Для решения данной проблемы, системы реального времени используют специализированные аллокаторы памяти. Куча также подвержена фрагментированию.*/

4) В нижней части адресного пространства процесса BSS, сегмент данных (data segment) и сегмент кода (text segment). BSS хранит неинициализированные переменные, чьи зачения явно не указаны в коде. Для сегмента BSS используется анонимное отображение в память, т.е. никакой файл в этот сегмент не мэппируется. В сегмент же data мэппируется часть образа программы, но изменения в данном сегменте не будут влиять на сам файл (“приватный” мэппинг). С указателями все сложнее - та же строка строка будет храниться в сегменте кода . В сегмент кода мэппируется часть исполняемого файла.

Расширение сегмента данных: int brk(void *endds); void *sbrk(intptr_t incr);

Page 40: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

Системные вызовы brk и sbrk используются для динамического изменения количества оперативной памяти, выделенной под сегмент данных процесса, делающего вызов. Это изменение достигается передвижением верхней границы сегмента данных и выделением соответствующего количества памяти. Далее под верхней границей понимается адрес сразу за концом сегмента данных. Увеличение этого адреса соответствует увеличению количества памяти, выделенной процессу. Вновь выделенная память заполнена нулями. Однако, если некоторая область памяти выделяется процессу повторно, ее содержимое будет неопределенным.

Системный вызов brk устанавливает верхнюю границу равной endds и соответственно изменяет количество памяти,выделенной процессу.

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

Верхняя граница сегмента данных не передвигается и системные вызовы brk и sbrk завершаются неудачей, если выполнено хотя бы одно из следующих условий:

[ENOMEM] Запрашиваемое действие привело бы к нарушению системного ограничения на размер данного процесса [см. ulimit(2)].

[EAGAIN] Общее количество системной памяти, предоставленной для физического ввода/вывода, временно оказалось недостаточным. Это может случиться, даже если системное ограничение на размер процесса не нарушается. 24. Взаимодействие между процессами (сигналы, семафоры, каналы...). Презентация:

• System V semaphores читать 67 вопрос • pipe канал • socket сокет • file файл • signal сигнал • message queue очередь сообщений • System V shared memory разделяемая память 6.3.3 Очереди сообщений Очередь сообщений - это заголовок, указывающий на связный список сообщений.

Каждое сообщение содержит 32-разрядную переменную типа, следующую за областью данных. Системный вызов msgpid = msgget(key, flag); /*IPC_CREAT, IPC_EXCL - флаги*/

Для помещения сообшения в очередь, необходимо произвести вызов: msgsnd (msgpid, msgp, count, flag), где msgp указывает на буфер сообщения         

(содержащий type после себя), count - общее количество байтов в сообщении, флаг IPC_NOWAIT используется для возврата ошибки, если сообщение невозможно отправить без блокировки (переполнение очереди).

Каждая очередь описывается в виде строки в таблице ресурсов очередей сообщений.

Page 41: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

Если msgtype = 0, msgrcv вернет первое по счету сообщение очереди, если больше нуля,

то первое сообщение типа msgtype. Если меньше нуля, то первое наименьшего типа, то есть типа, меньшего или равного абсолютной величине msgtype.

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

Когда процесс отправляет сообщение в очередь, ядро копирует его во внутренний буфер. Если другой процесс запросит сообщение, ядро скопирует его в адресное пространство получателя.

Разделяемая память.

Презентация: Разделяемая память - механизм для работы с общей для нескольких процессов

памятью. Сегмент разделяемой памяти хранится до его принудительного удаления.

Page 42: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

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

shmid = shmget (key, size, flag), где size - размер области. Затем процесс производит присоединение области виртуальной адресации:

addr = shmat (shmid, shmaddr, shmflag); shmaddr указывает на адрес, к которому может быть присоединена область разд. памяти. Если

он равен нулю, ядро вправе выбирать для области любой адрес. Флаг SHM_RND запрашивает у ядра присвоить shmaddr приблизительно, исходя из указанного диапазона. Флаг SHM_RDONLY указывает на необходимость присвоения области только для чтения.

Исключение области из своего адр. пространства: shmdt (shmaddr);

Файл в качестве взаимодействия 28 if ((fild = open("tmp_task3", O_RDWR | O_CREAT, 0600)) < 0 ) p_error("open"); 29 if (ftruncate(fild, sizeof(data_t)) < 0) p_error("ftruncate"); //обрезка или расширение файла 30 if ((p_data = (data_t*)mmap(NULL, sizeof(data_t), PROT_WRITE, MAP_SHARED, fild, 0)) < 0 )

pipe - каналы В традиционных реализациях UNIX программные каналы (pipe) представляют собой

однонаправленный неструктурированный поток данных фиксированного максимального

Page 43: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

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

Реализация программных каналов может быть осуществима различными способами. В традиционных вариантах применяется принцип ФС и ассоциация индексного дескриптора файла (inode) и элемента таблицы файлов для каждого канала. (Я так понимаю это неименованные каналы).

В ОС SysV представлены файлы FIFO - именованные каналы. Отличаются способами создания и доступа. Создается mknod, передавая имя файла и режим создания.

Раздел (8.4.2)

Семафоры

Сокеты

Сигналы

25. Средства синхронизации взаимодействия между процессами. Вахалия раздел 2.5

1) Ядро системы unix является реентерабельным, то есть в любой момент времени в ядре могут быть активны сразу несколько процессов. Так как все процессы используют одну и ту же копию структур данных ядра необходимо обеспечивать некоторую форму синхронизацию для для предотвращения порчи ядра.

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

3) Имеют место три ситуации, при возникновении которых необходима синхронизация: операции блокировки, прерывания, работа многопроцессорных систем.

4) Операция блокировки – это операция, которая блокирует процесс (то есть переводит процесс в спящий режим до тех пор, пока блокировка не будет снята). Существует некоторое количество объектов, которым необходима защита на время блокировки (пример стр 78). Для защиты таких объектов ядро ассоциирует с ними атрибут защиты lock. Ядро системы также ассоциирует с объектом еще один флаг wanted (необходимость). Флаг устанавливается на объект процессом, если тот ему необходим,

Page 44: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

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

5) На рисунке представлен алгоритм блокировки ресурсов. Описание не странице 78 Вахалии (2.5.1)

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

Page 45: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

7) Многопроцессорные системы порождают новый класс проблем синхронизации, так

как в этом случае защита ядра, основанная на отсутствии вытеснения, уже не может быть применена.

26. Управление процессами, классы и приоритеты. Утилиты nice и priocntl. Современная ОС может делать с процессом, все что душе угодно. В вытесняющей многозадачности любой процесс может быть прерван в любой момент выполнения. Про это в следующем пункте. Суть планирования в том, чтобы справедливо разделить ресурсы между процессами. Для гибкости планирования, процессы были поделены на классы: Пакетные: Всякие компиляторы и прочая фигня, которая просто что-то тихо вычисляет. Их эффективность определяется временем их выполнения среди других процессов в сравнении с временем их выполнения как единственной задачи в системе. Интерактивные: Приложения, которые постоянно взаимодействуют с пользователем: графические приложения, командные интерпретаторы. Большую часть времени они находятся в ожидании пользователя, однако они должны быстро обрабатывать полученный ввод иначе пользователю будет казаться, что все лагает. Собственно, здесь суть в том, чтобы задержка отклика после ввода была где-то около 50-150 миллисекунд. Реального времени: Всякие там игрушки, проигрыватели и т. д. Они требуют от планировщика гарантированных границ времени реакции, т. е. приложение должно выполняться на процессоре с определенной частотой - допустим какой-нибудь шутер хочет, чтобы система позволяла ему отрисовывать 60 кадров в секунду, планировщик должен ставить его на выполнение строго с определенным периодом. Nice

Page 46: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

Ну, собственно, nice - это утилитка, которая меняет p_nice для процесса. Чем меньше этот фактор любезности, тем выше приоритет процесса. Обычный юзверь не может его уменьшать, только увеличивать. Priocntl priocntl Установить параметры планировщика для указанного процесса или процессов. Её можно также использовать для выдачи текущей информации о конфигурации планировщика процессов системы или выполнения команды с явно заданными параметрами планировщика. Параметры: -c class задает класс, который надо установить. Допускаются аргументы: RT - процессы реального времени (real-time), TS - процессы с разделением времени (time-sharing), IA - интерактивные процессы (interactive). -d выдает параметры планировщика для заданного набора процессов. -e выполняет указанную команду с заданным классом и параметрами планировщика для всех процессов. -i тип идентификатора опция вместе с аргументами списка идентификаторов (если они заданы), задает один или несколько процессов, к которым необходимо применить команду priocntl. Интерпретация списка идентификаторов зависит от значения типа идентификатора. Пример: $ priocntl -d 25188 TIME SHARING PROCESSES: PID[/LWP] TSUPRILIM TSUPRI 25188 -30 -30 Получаем информацию о процессе, он имеет тип TS, лимит приоритета 30 и приоритет 30. 27. Планирование выполнения процессов (в ядре и в пространстве пользователя). Есть несколько стратегий планирования процессов, самая популярная на сегодняшний день - roundrobin: ОС хранит процессы, отсортированные по приоритету, в очереди выполнения и вызывает их циклически. Каждому процессу дается определенный маленький отрезок времени - квант, в течении которого процесс будет выполняться на процессоре. Размер кванта может определяться динамически, зависит от того, как ведет себя процесс. Планировщики ядра делятся на вытесняющие и кооперативные:

Page 47: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

Вытесняющие могут прервать выполнение работающего процесса, для того чтобы выбрать следующий, что позволяет операционной системе не зависать из-за одного сбойного процесса. В противовес вытесняющим, преимуществом кооперативной многозадачности является отсутствие необходимости организовывать разделение доступа к критическим секциям кода, что упрощает программирование, особенно перенос кода из однозадачных сред в многозадачные. FreeBSD: 1. На самом раннем этапе загрузки ядро вызывает функцию инициализации планировщика schedinit(), а затем вызывает sched_add(td, flags) для добавления thread0 в очередь планирования. 2. Ядро вызывает sched_clock(td) по таймеру в kern/kern_clock.c для перерасчета приоритета текущего процесса(точнее потока). Если он истратил свой квант времени, либо может быть вытеснен, то потоку устанавливается соответствующий флаг и он убирается из очереди выполнения. 3. При переходе потока в режим ожидания вызывается sched_sleep(td, pri) для пересчета приоритета. При возобновлении выполнения потока вызывается sched_wakeup(td), где сохраняется время сна и поток добавляется в очередь. 4. Если в данный момент нет потоков для выполнения, то из очереди выполнения ставится sched_idletd(), который периодически производит смену контекста для выбора другого потока. Для смены контекста вызывается mi_switch(flags, newtd)(newtd = NULL) которая вызывает sched_switch(td, newtd, flags), где выбирается следующий поток из очереди, соответственно через функцию sched_choose(). Приоритет процесса в очереди рассчитывается исходя из загруженности системы и процессора, на котором происходит выполнение, а также на основе класса процесса, заданного как диапазон приоритетов процесса. Пользователь может изменять приоритет процесса, через дополнительное значение "любезности" ( эт. в предыдущем билете распишу). Da System V Планировщик и диспетчер процессов явно разделены, классы приоритетов и сам диспетчер лежат в каталоге disp/. Диспетчер, собственно, лишь управляет процессами в очереди выполнения, добавляет и удаляет их, а для получения приоритетов вызываются специфичные функции, определенные для классов приоритетов: disp/rt.c - класс реального времени, disp/ts.c - разделения времени, disp/sysclass.c - системные, и, вот там рассчитывается приоритет процесса. Почитаю - побольше распишу. В userspace: Примеры планировщиков в юзерспейсах: http://wiki.minix3.org/doku.php?id=releases:3.2.1:developersguide:userspace_scheduling 28. Планироващик задач cron. izoomko: что же это? КОПИПАСТЕ Демон cron/ crontab Демоны – неинтерактивные программы, составляющие собственные сеансы и не принадлежащие ни одному из пользовательских сеансов. Демон cron – используется для периодического выполнения команд с определенными интервалами. Регулярные действия описываются инструкциями, помещенными в файлы crontab и в специальные директории (/var/spool/cron/crontabs). Пользователь может управлять планировщиком помощью команды crontab.

Page 48: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

Основные ключи: -e создается копия файла crontab, которая открывается с помощью текстового редактора или открывается пустой файл, если такой crontab не существует. После сохранения, заменяет исходный файл crontab на новый.

-l вывод содержимого файла crontab -r удаление файла crontab. Задания в файле crontab пишутся по одному в строке, включая в себя пять полей и

выполняемую команду. Поля:

1. минуты — число от 0 до 59 2. часы — число от 0 до 23 3. день месяца — число от 1 до 31 4. номер месяца в году — число от 1 до 12 5. день недели — число от 0 до 6 (0 – воскресенье)

Каждое из этих полей может быть представлено числом, списком чисел или интервалом. Звездочка обозначает интервал всех доступных значений. Пример: mm hh DD MM ww cmd

0 23 * * 6 rm * 2>/dev/null удаляет файлы, не выводя ошибок в субботу в 23.00.

29. Режим ядра и режим пользователя. izoomko: Современные процессоры имеют несколько уровней защиты. Unix использует два: режим пользователя и режим супервизора ( supervisor ) (читай, ядра). Очевидно, что ядро работает в привилегированном режиме, а пользователь- нет. Он не может выполнять некоторые команды процессора и не имеет доступа к ядерным функциям и структурам иначе как через системный вызов, потому что в таблице страниц у ядерных страниц установлен флаг супервизора ( supervisor ) и при обращении к ним процессор вырабатывает исключение. Так же нельзя выполнять код из одного режима, находясь в другом (но вполне есть способы переключаться: into, syscall, sysenter)

Page 49: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

http://plunkrrr.blogspot.ru/2013/08/blog-post.html 30. Жизненный цикл процесса (Создание...). После выделения и инициализации структуры proc системный вызов fork(2) вызывает функцию as_dup для дублирования адресного пространства процесса-родителя. Эта процедура вызывает as_alloc() для размещения новой структуры as, затем она просматривает список сегментов seg и дублирует их. Однако для реализации копирования-при-записи вызывается фукция hat_chprot(), для того чтобы гарантировать возникновение исключения при любой записи в дубликаты. Для структуры anon_map не вызывается копирование страниц, на самом деле клонируются лишь указатели на страницы.

31. Классификация потоков (нити ядра, прикладные нити, LWP ...).

● Нити ядра. OpenSolaris: /*/*/.../*/sys/thread.h ( сама нить ). http://tinyurl.com/hh53faw Ссылка на lwp нити ядра:

klwp_t *t_lwp; /* thread's lwp pointer */ /*/*/../*/sys/lwp.h ( её lwp ). http://tinyurl.com/hrqbg9p Ну и proc.h просто так.

Page 50: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

http://tinyurl.com/z67puzr Нити ядра рождаются и умирают в ядре; они не имеют никакого отношения к

прикладным процессам и служат целям ядра ( к примеру, ядра Solaris основано на нитях ); нити ядра разделяют ресурсы ядра и обладают собственным контекстом и стеком в ядре.

Основные атрибуты нити ядра.

1. Копия регистров ядра. 2. Приоритет и прочая информация для планирования. 3. Указатель на нить в очереди ожидания ресурсов. 4. Указатель стека. 5. Указатели на lwp нити и proc ( нить с собой и proc таксает O_o?); lwp есть абстракция

над нитью ядра. Нити ядра вытесняемые и малозатратные ( видимо, из-за того, что работают только в

пространстве ядра ); используются при проведении асинхронных операций; на них строится абстракция lwp, хотя не обязательно у нити этот lwp есть.

● Легковесные процессы ( lwp )

Код структуры OpenSolyarki смотри выше. LWP -- прикладная нить ядра, как бы парадоксально это ни звучало. А дело всё в том,

что LWP прикладная абстракция над нитью, то есть шедулинг происходит независимо от master-процесса, однако имеет общее АП и ресурсы ( ТД, обработчик сигналов и так далее ). LWP может иметь собственные маски сигналов, однако нельзя определить, какому LWP послали сигнал.

Структура. 1. Контекст регистров. 2. Аргументы, результат, код возврата syscall. 3. Информация об обработки сигнала. 4. Данные об использовании ресурса и данных профиля процесса. 5. Время передачи сигнала тревоги. ( Шта? ) 6. Указатель на нить ядра. 7. Указатель на proc.

● Прикладные нити pthreads source: http://tinyurl.com/zgzq5j struct pthread: http://tinyurl.com/jfyzynm

Прикладные нити ( представляются библиотеками С-threads, pthreads ) -- вычислительные блоки, обладающие собственным контекстом и ограниченным набором ресурсов; легковесный аналог процессов для библиотеки как легковесного аналога ядра.

Атрибуты прикладной нити. 1. ID нити. 2. Стек в АП процесса. 3. Приоритет. 4. Контекст регистров и область хранения. 5. Маска сигналов. 6. Область хранения нити.

Ядро _ничего_ не знает о прикладных нитях; их выполнение происходит путём мультиплексирования оных в lwp. Объекты синхронизации для прикладных нитях ( семафоры,

Page 51: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

локи и т.п. ) основываются на объектах синхронизации lwp ( судя по коду OpenSolyarki, но не могу найти, так что могло присниться это ). 32. Многопоточность ядра. В былые времена в ядре все было хорошо и просто - был один процессор, никто не пытался одновременно читать или изменять структуры ядра, но все это осталось в прошлом, когда появились многопроцессорные системы. В однопроцессорных системах ядру было достаточно защищать только те данные, которые были доступны обработчикам прерывания, а в остальных случаях можно было не заморачиваться. В многопроцессорных системах ядру нужно понимать, что в режиме ядра могут одновременно находиться несколько процессов на разных процессорах и что все структуры ядра следует блокировать при изменении. В FreeBSD, допустим, для этого используется мьютекс Giant, используемый чуть менее, чем повсеместно. В Linux используется механизм RCU, похожий на rwlocks. Он позволяет защищать указатель на структуру данных. При входе/выходе из критической области читатель должен вызвать процедуры rcu_read_lock() и rcu_read_unlock(). Тогда они будут помещены в список читателей и писатель не освободит используемый ими объект раньше, чем последний читатель закончит его использование (из тех, кто начал чтение до синхронизации и получил старый указатель). В то же время писатель удаляет указатель на старую структуру данных, модифицирует ее, возвращает на место указатель через rcu_assign_pointer, теперь новые читатели будут получать уже новую структуру. После того, как все “старые “ читатели закончили работать со старой структурой, она освобождается писателем. Точки вытеснения. Так как в монолитных ядрах обеспечение целостности ядра при многопоточности это одна большая беда, версии UNIX до SVR4 вообще не позволяли вытеснять что-то выполняемое в ядре. Т. е. если какая-нибудь ядровая вещь ожидала ввода/вывода это могло повесить систему. Такая ситуевина совершенно не устраивает приложения реального времени, ведь ОС должна гарантировать им, что они будут вызваны в определенные рамки времени и любая задержка для них критична. Тогда в SVR4 придумали такой костыль: в ядре вручную помечены участки кода, в которых ядро может быть вытеснено. Пример из VFS: /* * vn_create can take a while, so preempt. */ PREEMPT(); if (error = vn_create(pnamep, seg, &vattr, excl, mode, &vp, crwhy)) return error; PREEMPT(); Тогда приложения с более высоким приоритетом смогут вытеснить ядро хотя бы в некоторых ситуациях, чем и пользуются приложения реального времени. 33. Многопоточность процесса. 34. Варианты смешанной многопоточности (ядра, процессов). 35. Атрибуты, области (сегменты) и структуры данных потока. 36. Взаимодействие между потоками и средства синхронизации. 37. Подсистема управления вводом-выводом. Описание. 38. Взаимодействие драйверов с программной и аппаратной средой.

Page 52: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

Подсистема I/O -- прослойка между ядром и непосредственно драйверами системы. При работы с I/O ядро передаёт все операции драйверов подсистеме ВВ. которая отвечает за все аппаратно зависимые действия. ПIO не обладает информацией о свойствах дравейров; все драйвера -- абстракции. ПIO отвечает за управление доступом, буферизацией, присвоением имён и т.д. За взаимодействие с устройством отвечает сам драйвер; драйвер получает команды от ПIO через интерфейс драйвера устройства ( адреса обычно отмаплены в память, иногда для этого необходимы команды inb и outb, для записи информации в регистры контроллера устройства ). Соответственно, методы настройки пространства IO.

1. Если пространство IO отделено от основной памяти, то доступ происхожит с помощь команд inb, outb.

2. Отображение регистров в память; тогда при обращении к основной памяти данные будут записываться в регистры контроллера.

Методы передачи данных. 1. Программируемый IO. Данные передаются побайтно через процессор ( для

сивольных устройств ). 2. DMA, которому ядро передаёт все данные о нужных адресах, размер данных и

т.п.; устройство производит обмен данными в обход процессора. DVMA может взаимодействовать с MMU, передавай данные на виртуальные адреса.

Интерфейс взаимодействия.

1. Блочные устройства. Хранит данные и производит IO блоками фиксированного размера в произвольном порядке. Ядро взаимодействует с драверами с помощью структуры buf ( как выглядит? ), к котором содержится вся информация об операции. БУ обычно обмениваются с буферным кэшем. Каждый блок кэша ассоциируется со структурой buf. Доступ к данным свободный.

2. Символьные устройства. Используются для хранения и передачи данных произвольного размера. Некоторые устройства передают данные побайтно, некоторые используют буферизацию. СУ не поддерживают адресацию и не поддерживают операцию поиска.

Переключатель устройств -- структура, определяющая точки вхождения, поддерживаемые устроством. Для каждого типа устройства оно своё ( Для БУ bdevsw, для CE cdevsw ). Точки входа драйвера для обработки прерывания и инициализации не доступны из переключателя устройств, указываются в файлы конфигурации при сборке ядра ( init/start ). ПIO -- часть ядра, управляющая аппаратно-независимой частью операциий IO и взаимодействующую с драйверами устройств для обоработки операций. Пространство имён устройства:

● аппаратное идентифицирует устройства по контроллерам, к которым они подсоединены и логическому нормеру устройства в контроллере ( для пользователя имена приводятся в *удобочитаемый* вид );

● ядро идентифицирует утсройство по типу и паре номеров <major,minor> ( номер драйвера ( индекс в таблице переключателя), экземпляр устройства );

● файлы устройств ( специальный файл, не располагаемый на ФС и ассоциируемый с определённым устройством ( посредством полей в inode )).

Page 53: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

39. Файлы устройств(ноды). Назначение, принципы использования. iZoomko: ита, крч, про devfs. Там “лежат” файлы- отображения драйверов в ядре. Через них можно работать с устройствами. Типа framebuffer, hdd, tty etc. Это все, что можно сказать, яхз. 40. Классификация драйверов и устройств в/в. Традиционно юниксы делили все устройства на блочные и символьные: #define IO ввод/вывод Блочные устройства - это те, IO которых осуществляется через буферы, определенного в драйвере размера. Т.е. это всякие жесткие диски и прочая, и прочая. Символьные устройства - IO символами, т. е. байтами. Это очень широкий спектр устройств: от модемов, принтеров, терминалов до мышки и тачскрина. STREAMS - это отдельная ссанина, придуманная для того, чтобы код драйверов можно было переиспользовать. За основу была взята идея конвеера, где есть поток данных, проходящий через несколько уровней драйверов, каждый из которых производит какие операции и передает поток дальше.

Помимо этого ядро также может идентифицировать устройство по паре чиселков: Старший и младший номера устройства. ( major(3) ) Старший номер идентифицирует тип устройства, точнее его драйвер. Младший же номер идентифицирует экземпляр устройства. Например все диски будут иметь старший номер 5, но у каждого будет свой индивидуальный младший номер. 41. Драйвера модульно-поточной архитектуры (STREAMS). 42. Системные функции и взаимодействие с драйверами. 43. Идентификация, аутентификация и авторизация пользователя. GID, SGID, EGID. 44. Структура файлов /etc/passwd и /etc/group. GECOS. Атрибуты пользователя. Максимальное количество пользователей.

/etc/passwd -- файл со списком учётных записей. Структура записи: name:passwd:UID:GID:GECOS:home:shell В современных системах в поле passwd находится символ */x, а сами зашифрованные

MD5 пароли хранятся в файле /etc/shadow. Если в /etc/shadow не будет записи о пользователе, тот не сможет войти в систему с помощью login, но доступ к системе не будет запрещён ( rlogin ).

Page 54: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

Поле GECOS хранит дополнительную информацию о пользователе ( любая информация ). Существует с первых реализаций UNIX; предназначалось для хранения идентификатора пользователя в операционной системе GECOS ( впоследствии GCOS ), который использовался для доступа к печатной системе данной ОС.

/etc/group -- файл со списком групп. Структура записи: name:passwd:GID:user_list В user_list не указываются пользователи, для которых группа первичная. Система /etc/passwd -- /etc/group является основной, но не единственной. Существуют

также ряд баз пользователей. На Гелиосе используется LDAP, сетевая база данных, способная обслуживать несколько машин.

Максимальное число пользователей. В современных пинуксах до 4 биллионов. В

солярке? 45. Системные вызовы. Определение. Применение. iZoomko: Системный вызов - обращение прикладного процесса к ядру операционной системы для выполнения некоторой операции, осуществляется обычно (ок, на старых машинах) через процессорное прерывание или специальную инструкцию процессора (syscall для AMD64 и sysret, sysenter/sysexit) Более чем хорошо: http://minix3.ru/docs/syscall.pdf 46. Схема компиляции и сборки исполняемого файла.

(слева - Робачевский, справа - из ЯСП)

СОГЛАСНО ЯСП: Препроцессор (преобразование текста в текст, получаем программу на исходном языке программирования с текстовыми заменами), компилятор (из каждого файла с исходным кодом получаем файл с машинным кодом, который не готов к исполнению, ибо не связан с другими файлами, к которым обращается; набор объектных файлов), компоновщик (установка связей между разными файлами, сборка их в один исполняемый),

Page 55: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

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

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

Как и большинство сложных программ в системе UNIX, компилятор состоит из нескольких выполняемых файлов. Основной из команд, с которой приходится иметь дело пользователю, является команда cc. Ее функцией является проанализировать введенную командную строку и выполнить действия, предписанные указанными после имени команды параметрами. Для выполнения описанного выше требуется вызвать программы: /lib/cpp - препроцессор; /lib/cc0 - синтаксический анализатор; /lib/cc1 - генератор кода; /bin/as - ассемблер; /bin/ld - загрузчик.

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

При прохождении объектных файлов через компоновщик ld получается исполняемый файл. Объектные файлы в UNIX системе имеют формат ELF(executable and linkable format)

Базовая структура памяти для процессов, загруженных из

исполняемого файла ELF изображена слева. Процесс имеет сегменты кода (text), данных (data), стека (stack). Как видно из рисунка, размер сегментов данных и стека может изменяться, а направление этого изменения определяется форматом исполняемого файла. Размер стека автоматически изменяется операционной системой, в то время как управление размером сегмента данных производится самим приложением. Сегмент данных включает инициализированные данные, копируемые в память из соответствующих разделов исполняемого файла, и неинициализированные данные, которые заполняются нулями перед началом выполнения процесса. Неинициализированные данные часто называют сегментом BSS. Формат ELF имеет файлы нескольких типов, которые до сих пор мы

называли по-разному, например, исполняемый файл или объектный файл. Тем не менее стандарт ELF различает следующие типы:

1. Перемещаемый файл (relocatable file), хранящий инструкции и данные, которые могут быть связаны с другими объектными файлами. Результатом такого связывания может быть исполняемый файл или разделяемый объектный файл.

2. Разделяемый объектный файл (shared object file) также содержит инструкции и данные,

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

Page 56: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

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

3. Исполняемый файл хранит полное описание, позволяющее системе создать образ

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

Имя исполняемого файла по умолчанию a.out. 47. Средства компиляции программ. Утилиты (cc, gcc, clang, make). сс - компилятор С gcc - GNU версия компилятора С clang - это транслятор для C-подобных языков, созданный специально для работы на базе LLVM((Low Level Virtual Machine) — это универсальная система анализа, трансформации и оптимизации программ). Комбинация Clang и LLVM представляет собой полноценный компилятор и предоставляет набор инструментов, позволяющих полностью заменить GCC. Благодаря архитектуре, основанной на библиотеках, Clang (как и LLVM) легко встраивается в другие приложения. Одной из главных задач Clang является поддержка инкрементной компиляции, позволяющей более тесно интегрировать компилятор и графический интерфейс среды разработки, в отличие от GCC, который был создан для работы в классическом цикле «компиляция-линковка-отладка». В отличие от GCC, ориентированного преимущественно на кодогенерацию, Clang стремится предоставить универсальный фреймворк для парсинга, индексации, статического анализа и компиляции языков семейства Си. В частности, Clang не производит упрощений исходного кода на этапе парсинга (как это делает GCC), гарантируя точное воспроизведение исходного текста в абстрактное синтаксическое дерево. В отличие от GCC, Clang изначально спроектирован для максимального сохранения информации в ходе процесса компиляции, в том числе сохранения «внешнего вида» исходного кода. Эта особенность позволяет Clang создавать развернутые контекстно-ориентированные сообщения об ошибках, понятные как для программистов, так и для сред разработки. Модульный дизайн компилятора позволяет использовать его в составе среды разработки для индексирования кода, подсветки синтаксиса и реорганизации кода. Clang поддерживает большинство распространенных опций GCC. make - утилита, автоматизирующая процесс преобразования файлов из одной формы в другую. Чаще всего это компиляция исходного кода в объектные файлы и последующая компоновка в исполняемые файлы или библиотеки. Утилита использует специальные make-файлы, в которых указаны зависимости файлов друг от друга и правила для их удовлетворения. На основе информации о времени последнего изменения каждого файла make определяет и запускает необходимые программы. (izoomko: в конце описание подробнее про make) 48. Параметры, передаваемые gcc/cc. 49. Параметры, переданные программе (argc,*argv[]), переменные окружения. Izoomko: При запуске программы семейством системных вызовов exec аргументом передаются некоторые параметры запуска. Ядро кладет их на вершину стека(?), подсчитывает их количество и передаёт в main int argc и нультерминированный массив строк- аргументов программы. Переменные окружения смотреть дальше

Page 57: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

Максимальный объем памяти для хранения параметров и переменных окружения программы ограничен величиной ARG_MAX, определенной в файле <limits.h>. Установка, получение значений переменных окружения. 50. Установка, получение значений переменных окружения. iZoomko:

1) Во- первых, в unix не очень православна следующая сигнатура для main int main(int argc, char *argv[], char *envp) Потому что не входит в Single Unix Standart v3. Юзать можно на свой страх и риск

2) extern char **environ; - вполне способ получить нультерминированный массив

переменных окружения и далее делать с ними все, что душе угодно. 3) Но по- хорошему надо юзать getenv(3C) (only one specified by C standart), putenv(3C)

specified by POSIX 51. Заголовочные файлы. Определение, применение. iZoomko: Заголовочным файлом называется файл, включаемый в указанное место в файл с кодом программы. В случае с языком C это способ использовать заранее определенные типы данных (в т.ч. структуры, перечисления, объединения), прототипы функций и макроопределения. Вообще такой файл является синтаксически корректным с точки зрения компилятора, но обычно (привет, Linux и C++) он не содержит исполняемой логики. Как правило заголовочные файлы так же содержат Include Guard, чтобы не включать одни и те же заголовки в код более одного раза. #ifndef H_HEADERFILE #define H_HEADERFILE ...some data… #endif 52. Библиотечная (libc) система регистрации ошибок. Переменная errno. Библиотека языка Си предоставляет пользователю набор достаточно полезных инструментов, которые в конечном счете почти всегда являются оберткой над системным вызововом или группой вызовов ( как popen ). Заголовочный файл <sys/errno.h> содержит макроопределения всех кодов ошибки в системе с сответствующим номером и комментарием( например, #define EPERM 1 /* Not super-user */ ) Библиотека предоставляет пользователю функцию perror(string), которая выводит заданную строку + описание случившейся ошибки, переменную errno, содержащую код последней ошибки и функцию strerror(errno), возвращающей указатель на строку с описанием ошибки #errno. Важно заметить, что значение errno не обнуляется при успешном выполнении команды В случае с многопоточными приложениями следует компилировать код, использующй errno, с включением библиотеки libthread (-lthread 4 gcc, -mt 4 cc) 53. Основные системные вызовы для работы с файлами. by iZoomko

Page 58: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

см. pdf в 45 вопросе, там целая группа сисколлов для управления файлами 54. Дескрипторы основных потоков. 55. Структура dirent. by iZoomko typedef struct dirent { ino_t d_ino; /* "inode number" of entry */ off_t d_off; /* offset of disk directory entry */ unsigned short d_reclen; /* length of this record */ char d_name[1]; /* name of file */ } dirent_t; Так выглядит filesystem independent структура dirent сопляриса. d_name[1] как бэ намекает на то, что к массиву структур dirent нифига не просто обращаться. Это значит, что размер структуры тянется с именем. В общем- то комменты вполне точно и ясно говорят о том, из чего оно состоит. Используется структура (а точнее- ссылка на нее), когда необходимо прочитать директорию. Тогда мы итеративно один за одним можем получить содержимое каталогов (потому что есть d_reclen и d_name в конце структуры расположен). Вы ведь помните, что все есть файл? :) 56. Структура stat, семейство системных вызовов stat. ( SVR4 ) struct stat { o_dev_t st_dev; /* ID дейвайса, содержащего файл. */ o_ino_t st_ino; /* inode */ o_mode_t st_mode; /* тип файла*/ o_nlink_t st_nlink; /* количество ссылок */ o_uid_t st_uid; o_gid_t st_gid; o_dev_t st_rdev; /* ID устройства, если файл специальный */ off_t st_size; time_t st_atime; time_t st_mtime; time_t st_ctime; }; int stat( const char *path, struct stat* buf ); int fstat( int fd, struct stat *buf ); int lstat( const char *path, struct stat *buf ); /* path -- symbolic link */ int fstatat( int fd, const char* path, struct stat *buf );

fstatat работает аналогично stat и lstat; если путь относительный, то используется fd взамен CWD. 57. Межпроцессное взаимодействие (каналы, сокеты, очереди сообщений). izoomko: The pipeline concept was invented by Douglas McIlroy and first described in the man pages of Version 3 Unix.[4] McIlroy noticed that much of the time command shells passed the output file from

Page 59: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

one program as input to another. His ideas were implemented in 1973 when ("in one feverish night", wrote McIlroy) Ken Thompson added the pipe() system call and pipes to the shell and several utilities in Version 3 Unix. "The next day", McIlroy continued, "saw an unforgettable orgy of one-liners as everybody joined in the excitement of plumbing." McIlroy also credits Thompson with the | notation, which greatly simplified the description of pipe syntax in Version 4.[5][4] The idea was eventually ported to other operating systems, such as DOS, OS/2, Microsoft Windows, and BeOS, often with the same notation. Каналы - см. 65 Сокеты - см. 72 Очереди: см. 71 struct msg { struct msg *msg_next; /* ptr to next message on q */ long msg_type; /* message type */ ushort msg_ts; /* message text size */ short msg_spot; /* message text map address */ }; Структура, описывающая отдельное сообщение. msg_spot вообще должен быть указателем на char*, но чет создатели упоролись, наверное. Я: структура похожа на правду, в самих мэседжах при отправке сообщений структура сообщения состоит из числа - типа и массива чаров(не указателя а самого массива) и при отправке получении есть параметр определяющий кол-во байт сообщения. да и очередь пишут сообщения процессы разные, для передачи этого массива либо ядру бы пришлось лезть в память чужого процесса, либо нужно всегда передавать информацию полностью. я:2 только не понятно почему тут 2 структуры описывающие объекты очереди. если первое это чисто сообщение до отправки или после принятия то процессы ничего не знают о следующих элементах. http://www.tldp.org/LDP/lpg/node27.html#SECTION00742000000000000000 struct msqid_ds { struct ipc_perm msg_perm; /* operation permission struct */ struct msg *msg_first; /* ptr to first message on q */ struct msg *msg_last; /* ptr to last message on q */ ulong msg_cbytes; /* current # bytes on q */ ulong msg_qnum; /* # of messages on q */ ulong msg_qbytes; /* max # of bytes on q */ pid_t msg_lspid; /* pid of last msgsnd */ pid_t msg_lrpid; /* pid of last msgrcv */ time_t msg_stime; /* last msgsnd time */ long msg_pad1; /* reserved for time_t expansion */ time_t msg_rtime; /* last msgrcv time */ long msg_pad2; /* time_t expansion */ time_t msg_ctime; /* last change time */ long msg_pad3; /* time expansion */ long msg_pad4[4]; /* reserve area */

Page 60: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

}; Основная структура, описывающая очередь сообщений. Детишки взрослые, английский знаем, комментарии сможем сами раздуплить. Работает эта ссанина так:

1) Получили очередь msgget(2) 2) Отправляем, получаем сообщения (msgrcv(2), msgsnd(2)) 3) Контролируем очередь msgctl(2) (в т.ч. удаляя ее ключом IPC_RMID) 4) Места в очереди соощений не бесконечно совсем. Можно контролировать размер через

msgctl(2) Может быть захардкожено ограничение на размер очереди!!! SVR4 64k, Linux too 58.Организация именованного канала, для взаимодействия процессов. mkpipe(1), mkpipe(2), см. 65 59.Организация неименованного канала, для взаимодействия процессов. pipe(2), см 65 60. Семейство функций fork(2)и принципы работы с ними. 61. Семейство функций exec(2) и принципы работы с ними. 62. Функция popen(3). Реализация с помощью системных вызовов. 63.Принципиальные различия между popen(3) и exec(2). 64. Функция pipe(2) и массив дескрипторов (реализация механизма). См. 65 65. FIFO. Реализация механизма в ядре и в пространстве пользователя. izoomko: Kernel space: В SVRv4 механизм FIFO реализован через жопу через драйвер STREAMS и файловую систему fifofs Когда ядро просят найти файл, то если тип этого файла блочный, символный или именованный канал, то вызывается процедура specvp() для получения vnode файла, которая вызовет fifovp, возвращая vnode fifofs и инициализируя v_op. Теперь при обращении к открытому файлу ядро будет работать с семейством функций fifofs_ 339 /* 340 * send SIGPIPE and return EPIPE if ... 341 * (1) broken pipe 342 * (2) FIFO is not open for reading 343 * return 0 if... 344 * (1) no stream 345 * (2) user request is 0 and STRSNDZERO is not set 346 * While the stream is flow controlled.... 347 * - if the NDELAY/NONBLOCK flag is set, return 0/EAGAIN. 348 * - unlock the fifonode and sleep waiting for a reader.

Page 61: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

349 * - if a pipe and it has a mate, sleep waiting for its mate 350 * to read. 351 */ вот такое говно происходит на записи. /* 277 * Read from a pipe or FIFO. 278 * return 0 if.... 279 * (1) user read request is 0 or no stream 280 * (2) broken pipe with no data 281 * (3) write-only FIFO with no data 282 * (4) no data and delay flags set. 283 * While there is no data to read.... 284 * - if the NDELAY/NONBLOCK flag is set, return 0/EAGAIN. 285 * - unlock the fifonode and sleep waiting for a writer. 286 * - if a pipe and it has a mate, sleep waiting for its mate 287 * to write. 288 */ а такое на чтении В итоге: писать можно, только если кто- то читает. Данные копируются от отправителя-в ядро-получателю. EZ, ёпты. User space: В userspace все безумно просто. Есть системный вызов mknod, который при передаче параметра S_IFIFO создает файл path. Все механизмы, в названии которых есть pipe, работают на базе той дичи, что я написал выше. Системный вызов pipe(2) делает що? Возвращает 2 дескриптора. По ним создаются 2 vnode с набором операций от fifos и сответствующими приблудами типа v_stream. Они проставляются друг другу в fn_mate и получается полнодуплексный поточный канал связи. Очевидно, что mkfifo работает абсолютно так же. Только vnode fifoшечки создаются в другое время, мелочи :) 66. Поток, функция потока. Потоки POSIX. Читайте :3 : https://computing.llnl.gov/tutorials/pthreads/ pthreads source: http://tinyurl.com/zgzq5j struct pthread: http://tinyurl.com/jfyzynm

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

Page 62: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

динамический объект, в процессе представленный отдельный точной управления и выполняющий код от данной точки.

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

Интерфейс потоков. 1. Create/destory. 2. Перевод в режим ожидания и вывод из него. 3. Назначение приоритетов нитей. 4. Планирование выполнения нити и переключение контекста. 5. Средстве синхронизации. 6. Обмен между нитями.

Жизненным циклом прикладных нитей управляет библиотека. Pthreads.

Интерфейс pthread.

1. pthread_create( ) -- создание потока. Завершение потока происходит вызовами pthread_join() из другого потока, при создании pthread_detach() ( тогда структура потока самостоятельно освободится ), pthread_exit() из завершаемого потока, pthread_cansel из другого потока ( завершение при наступлении cancellation point ).

2. pthread_attr_* -- работа с атрибутами потока ( к примеру, установить размер стека для потока ). pthread_set* -- установить параметры исполнения потока ( к примеру, установка параметров шедулинга ).

3. pthread_mutex_* -- работа с мьютексами, pthread_cond_* -- работа с условными переменными, pthread_rwlock_* -- работа с rwlocks. sem_* -- работа с семафорами. В чём сути сущностей? mutex -- взаимное исключение, аналог семафора для одного потока. CV -- условная переменная, на которой блокируется нить до наступления события ( информирование о котором происходит по *сигналу* pthread_cond_signal ). rwlocks -- защёлки, работают как мьютексы в целях синхронизации операций чтения и записи.

Page 63: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

67. Семафоры ( SysV и POSIX ) и мьютексы как объекты синхронизации потоков.

Объект SysV POSIX

Семафор Семейство функций: struct sembuf { ushort_t sem_num; /* semaphore # */ short sem_op; /* semaphore operation */ short sem_flg; /* operation flags */ };

● semctl(); -- операции над ресурсом.

● semget(); -- создание ресурса семафоров.

● semids(); -- ● semop(); -- операции над

отдельными семафорами. ● semtimedop();

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

Семейство функций: typedef struct { /* this structure must be the same as sema_t in <synch.h> */ uint32_t sem_count; /* semaphore count */ uint16_t sem_type; uint16_t sem_magic; upad64_t sem_pad1[3]; /* reserved for a mutex_t */ upad64_t sem_pad2[2]; /* reserved for a cond_t */ } sem_t;

● sem_wait ● sem_init ● sem_post ● sem_getvalue ● sem_destroy

Семафор предназначен для синхронизации потоков по действиям и по данным. Семафор – это защищенная переменная, значения которой можно опрашивать и менять только при помощи специальных операций инкремента и декремента и операции инициализации. Семафор может принимать целое неотрицательное значение. Семафоры посиксовые менеждатся библиотекой, хотя есть реализации на API SysV.

Мьютексы POSIX. Мьютекс позволяет потокам управлять доступом к данным. При использовании мьютекса только один поток в определенный момент времени может заблокировать мьютекс и получить доступ к разделяемому ресурсу . При завершении работы с ресурсом поток должен возвратить «лицензию», разблокировав мьютекс. Если какой-либо поток обратится к уже заблокированному мьютексу, то он будет вынужден ждать разблокировки мьютекса потоком, владеющим им. 68. Условные переменные как средство синхронизации потоков. https://sourceware.org/git/?p=glibc.git;a=tree;f=nptl Функции:

● pthread_cond_wait (condition,mutex) -- ожидание сигнала; блокирует вызывающий поток; используется с мьютексов в целях, внезапно, синхронизации.

● pthread_cond_signal (condition) -- отправка сигнала одному потоку ( какому ? ) ● pthread_cond_broadcast (condition) -- отправка сигнала всем ожидающим.

Условная переменная позволяет потокам ожидать выполнения некоторого условия (события), связанного с разделяемыми данными. Над условными переменными определены

Page 64: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

две основные операции: информирование о наступлении события и ожидание события. При выполнении операции «информирование» один из потоков, ожидающих на условной переменной, возобновляет свою работу. Условная переменная всегда используется совместно с мьютексом. Перед выполнением операции «ожидание» поток должен заблокировать мьютекс. При выполнении операции «ожидание» указанный мьютекс автоматически разблокируется. Перед возобновлением ожидающего потока выполняется автоматическая блокировка мьютекса, позволяющая потоку войти в критическую секцию, после критической секции рекомендуется разблокировать мьютекс. При подачи сигнала другим потокам рекомендуется так же функцию «сигнализации» защитить мьютексом. 69. Реализация многопоточности и физического параллелизма потоков. http://www.ibm.com/developerworks/ru/library/l-linux_kernel_70/ 5.6.2 70. Реализация векторного ввода-вывода. Структура iovec.

Векторный ввод/вывод позволяет производить неделимые операции, путём оперирования вектором буферов.

Вызовы: int readv( int fd, const struct iovec *iov, int count ); int writev( int fd, const struct iovec *iov, int count );

struct iovec { void *iov_base; /* сам буфер. */ size_t iov_len;

}; При вызове writev ядро создаёт структуру uio и инициализирует её, используя входные аргументы, и передаёт указатель на неё функциям нижнего уровня, производящим I/O. ( SVR4: uts/i386/sys/uio.h ) typedef struct uio {

iovec_t *uio_iov; /* pointer to array of iovecs */ int uio_iovcnt; /* number of iovecs */ off_t uio_offset; /* file offset */ short uio_segflg; /* address space (kernel or user) */ short uio_fmode; /* file mode flags */ daddr_t uio_limit; /* u-limit (maximum "block" offset) */ int uio_resid; /* residual count */

} uio_t

Page 65: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

71. Реализация сигналов на уровне ядра и их отличие от очередей сообщений. by iZoomko Что такое сигналы?

Сигналы – это программные прерывания. Сигналы разделяются на «стандартные» и «сигналы реального времени».

Начнем с сигналов стандартных. В структуре каждого процесса. содержится в том числе мета сигналов. Для SVR4 это следующее содержимое области u (struct user inside uts/i386/sys/user.h):

И части структуры proc процесса (struct proc inside uts/i386/sys/proc.h):

Теперь подробнее, что с этим всем происходит.

Генерация: Тем или иным образом, сигнал генерируется системным вызовом kill(2) (справедливо для SVR4).

Page 66: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

(proc.h) 93 k_sigset_t p_ignore; /* ignore when generated */ Рабочих битов в этом сете столько, сколько сигналов умеет система (32)

Если kill увидит в struct proc:p_ignore “1” на месте сигнала (номер сигнала- позиция бита в битовой маске), то сигнал будет попросту проигнорирован.

Если он уже был установлен, то ничего не произойдет (всего 1 бит. Пока никаких очередей)

Иначе в битовой маске struct proc:p_sig бит под номером сигнала будет установлен в 1. Если процесс находится в прерываемом сне (то есть ожидает ресурс или сигнал), то он будет разбужен при генерации сигнала. Больше того, SIGSTOP/SIGCONT обрабатываются так же на этапе генерации сигнала.

Доставка: Процесс проверяет маску ожидающих сигналов struct proc:p_sig каждый раз при возвращении из режима ядра, а так же при входе/выходе в прерываемый сон. Функция os/sig.c:issig() проверяет, установлен ли хотя бы сигнал, и если установлен, то блокируется ли он. (struct proc:p_hold). Если все православно, сигнал сохраняется в struct proc:p_cursig

Обработка: Заданное сигналу действие выполняется os/sig.c:psig().

ЧСХ, там можно найти форс сигнала SIGKILL (ибо он приоритетнее любого другого и вообще как бе безусловный)

Немношк приколюх с ptrace, либо (см ниже) Далее идет выполнение заданного сигналу действия. Если процесс хочет siginfo, ему

запиливают siginfo из struct proc:p_curinfo. Если дефолтное действие- игнор, проваливаемся через все условия и роняем процесс вызовом exit.

В маску заблокированных сигналов добавляется u_sigmask Если на сигнал установлен флаг SA_NODEFER, то обрабатываемый сигнал не добавляется к маске заблокированных Если SA_RESETHAND, то handler сигнала сбрасывается Далее выполняетя sendsig, который переключает процессор в режим задачи и запускает пользовательский обработчик (ОЧЕНЬ machine-specific штука. Я ее даже не пытаюсь понять). Обработчик выполняется,возможно, с альтернативным стеком (struct user:u_sigaltstack). Выполнение пользовательского обработчика завершается системным вызовом sigreturn/

Таким образом, если у вас есть пачка сигналов с недефолтными обработчиками, то они будут выполнены последовательно, потому что есть sigreturn, который как бэ тоже syscall. В принципе так работают все сигналы в той или иной степени. Есть еще сигналы реального времени. Их отличие от классических в том, что там повторяющиеся сигналы не теряются, а хранятся до обработки в ядре в списке и, офк, доставляются в порядке отправки (FIFO, в общем)

Сравнение сигналов и message queue

Сигнал Реалтайм сигнал Очередь сообщений

Page 67: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

Повторяющиеся сигналы отваливаются

Сохраняются в очередь K.O. (очередь сообщений)

Можно отправить только тем, на кого есть права (потому что приходящие сигналы вызывают у неподготовленных процессов острое жжение)

Очередь сигналов тому, кому можно эту очередь отправлять

Отсылается вообще в никуда. Читает тот, у кого есть права читать очередь

Можно установить православный обработчик а-ля callback

+ Надо вытаскивать из очереди специальным вызовом

72.Сокеты BSD и UNIX domain, принципы работы с ними Читайте :3: https://scoecomp.files.wordpress.com/2014/02/2003-unix-network-programming-vol-1-3rd-ed.pdf http://lxr.free-electrons.com/source/net/socket.c http://lxr.free-electrons.com/source/include/linux/socket.h http://lxr.free-electrons.com/source/net/core/sock.c http://lxr.free-electrons.com/source/net/unix/af_unix.c Сокет -- программный интерфейс ( и не только, но это лишнее ), предоставляющий полнодуплексный канал коммуникации между двумя единицами соединения. Представляется структурой, описывающей протокол, семейство адресов ( AF ), указатель на операции для данного типа, готовый пакет для отправки, устройство, с которым связан сокет и так далее. API сокетов:

struct sockaddr { sa_family_t sa_family; char sa_data[14]; /* pinux */

}; sockaddr общий интерфейс адресов для разных семейств протоколов. int socket( int domain, int type, int protocol );

domain -- семейство адресов сокета ( AF_INET, AF_UNIX, AF_INET6 ) . Отличие от PF_* ? Его нет.

type -- тип сокета ( SOCK_STREAM, SOCK_DGRAM, SOCK_RAW, ... ). protocol -- протокол для данного семейства и данного тиап; обычно для каждого типа один вид протокола.

int setsockopt( int sock, int level, int opt, void *optval, int optlen ); /* С аналогичной get*. */ sock -- дескриптор сокета. level -- протокол, для которого устанавливается опция. opt -- имя опции. optval, optlen -- значение и его длина; обычно устанавливается в 1 ( для снятие опции -- 0 ).

Функция позволяет установить дополнительные параметры сокета ( *переиспользование* адреса, броадкаст, ). int bind( int sock, struct sockaddr*, int len );

Биндит сокет на адрес.

Page 68: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

int connect( int sock, struct sockaddr*, int len ); Коннектится к серверу, адрес которого указан в struct sockaddr ( SOCK_STREAM ); для

SOCK_DGRAM может использоваться для установления адреса назначения всем пакетам. int listen( int sock. int backlog );

backlog -- максимальное количество клиентов для обслуживания. Используется для того, чтобы проинформировать систему о том, что сокету нужно принять соединение ( имеет смысл лишь для TCP; вызов предоставляет переход конечного автомата TCP в состояние LISTEN ). int accept( int sock, struct sockaddr* c_sock, int len );

s_sock -- зарезервированный сокет для клиента Блокируется до запроса на соединение.

Сокеты разделяются по семействам адресов:

● сетевые ( BSD ); ● UNIX domain; ● прочие ( что за прочие? откуда? зачем ? ).

Сокеты BSD:

struct sockaddr_in { sa_family_t sin_family; uint16_t sin_port; struct in_addr sin_addr; /* В структуре только __u32 s_addr, видимо, для

совместимости. */ uint8_t sin_zero; /* Для выравнивания, как понимаю. */

}; struct sockadd_ll { /* link level. map -s 7 packet */ }; UNIX domain:

struct sockaddr_un { sa_famliy_t sun_family; uint8_t sun_path[109];

}; Данные хранятся в сокете ( *двунаправленом* пайпе ). Для UNIX domain сокетов есть вызов socketpair, создающий полнодуплексный канал в

обход стандартным интерфейсам сокетов. int socketpair( int family, int type, int proto, int sv[2] ); sv[2] -- пара дескрипторов сокета. Имеет смысл, когда есть возможность передать дескриптор другому процессу ( fork, к

примеру ). Различия работы сокетов сводятся к природе сокетов. Сам же интерфейс поддерживает любые типы. Операции над разными типами, очевидно, разные, так что структура, описывающая сокет, хранит указатели на интерфейсные функции, реализации которых зависят от типа сокета и устанавливаются во время создания ( ??? ) сокета 73. Функция mmap(2), анонимная память и отображение файлов в память. 74. Инструкции IN/OUT и работа с устройствами в UNIX.

Page 69: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

http://wiki.osdev.org/Everything_about_ports outb(2) В UNIX для ввода/вывода через порты используется семейство функций in*, out*, суффикс b означает байты, w - слова, _p - такие функции ожидают окончания операции ввода/вывода. Например inb_p(unsigned short int port) - получить байты из указанного порта, при этом ожидать окончания операции. Это все используется преимущественно в драйверах, и, естественно, очень зависит от архитектуры. unsigned char inb (unsigned short _port){

unsigned char rv; __asm__ __volatile__ ("inb %1, %0" : "=a" (rv) : "dN" (_port)); return rv;

} void outb (unsigned short _port, unsigned char _data){

__asm__ __volatile__ ("outb %1, %0" : : "dN" (_port), "a" (_data)); } 75. Функции link(2) и unlink(2), удаление файлов, работа с ссылками. 76. Функции symlink(2) и readlink(2). Работа с символьными ссылками и их атрибуты. 77. Работа с каталогами средствами libc. Функции opendir(3), readdir(3). 78. Режимы доступа к файлам в UNIX. Позиция внутри файла. 79. Advisory и mandatory блокировки. Реализация с помощью функций fcnt(2) и chmod(2). Читайте :3 : https://www.opennet.ru/soft/ruprog/frlock.txt http://beej.us/guide/bgipc/output/html/multipage/flocking.html

int fcnt( int fd, int cmd, /* args */ ); cmd:

FD_SETLK -- установить блокировку. FD_SETLKW -- ждать, пока блокировка не установится. FD_GETLK -- получить блокировку.

Принимает аргументом struct flock*. struct flock {

... short l_type; /* F_RDLCK, F_WRLCK, F_UNLCK */

short l_whence; /* SEEK_SET, SEEK_CUR, SEEK_END */ off_t l_start; /* Начало блокирови. */ off_t l_len; /* Количество заблокированных байт. */ pid_t l_pid; /* PID процесса блокировки. */

... }; int fchmod( fd, mode_t mode ); Advisory -- добровольная ( необязательная/рекомендательная ) блокировка;

поддерживается на уровне userspace, ядро не производит тяжёловесных операции, заполняя

Page 70: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

лишь необходимые поля struct file. Позволяет доступ к файлу нескольких связанных процессов, однако не гарантирует эксклюзивный доступ ( процесс-потомок, к примеру, может просто проигнорировать блокировку ).

Advisory блокировка организуется использованием fcntl ( установка struct flock, вызов fcntl( fd, FD_SETLK, &lock)).

Mandatory -- обязательная блокировка; гарантирует уникальный доступ к заблокировнным файлам; запрещают процессу получать доступ с помощью функций read или write к данным, которые ранее были блокированы другим процессом через fcntl. Контролируется вызовами creat, open, read, write. Поддерживается ядром. Использование не рекомендуется. Будет ли задействован контроль блокировки при любых системных вызовах, обслуживающих ввод/вывод, выясняется в момент этих вызовов в зависимости от режима доступа к файлу. Чтобы такой контроль осуществлялся, файл должен быть обычным, со взведенным битом переустановки идентификатора группы и без права на выполнение членами группы. Если эти условия не выполняются, все блокировки сегментов будут слабыми. Сильная блокировка может быть обеспечена следующим исходным текстом: #include <sys/types.h> #include <sys/stat.h> int mode; struct stat buf; . . . if (stat (filename, &buf) < 0) { perror ("программа"); exit (2); } /* Получение текущего режима доступа */ mode = buf.st_mode; /* Удаление разрешения на выполнение членами группы */ mode &= (S_IEXEC >> 3); /* Взведение бита переустановки идентификатора группы */ mode |= S_ISGID; if (chmod (filename, mode) < 0) { exit (2); } . . . С файлами, в которых должны блокироваться сегменты, не должно быть связано каких бы то ни было прав на выполнение. Это требование вызвано тем, что операционная система не поддерживает протокол блокировки сегментов при выполнении файла. Помимо рассмотренного способа, сильная блокировка файла может быть легко установлена с использованием утилиты chmod(1): chmod +l файл. 80. Код возврата функции, системного вызова. Проверка корректности операции.

Page 71: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

81. Сценарии сборки Makefile. Назначение, принципы формирования. iZoomko: DISCLAIMER: за точность высказываний в области алгоритмов я не отвечаю, ибо неуч Сценарий сборки Makefile - говоря в общем и как есть на деле, это система, запускающая цели в порядке возрастания индексов вершин после топологической сортировки (такой порядок нумерации вершин орграфа, что для ребра (v, u) index[v] < index[u]; то есть если проще, то такой порядок запуска целей, что для запуска цели i требуется удовлетворить все ее зависимости V_i) Если говорить проще, это скрипт сборки проекта, учитывающий зависимости одних целей от других. Зачастую для сборки одного исполняемого файла требуется выполнить линковку N объектных файлов (т.е. цель “сборка” зависит от N целей “объектный файл”, которые в свою очередь могут зависимость от исходных файлов (для перекомпиляции только измененных файлов) ), а для этого их надо скопилировать (в описании каждой цели что- то типа gcc file.c -o file.o (в этом примере имеется циклическая зависимость, что не очень хорошо для топологической сортировки, потому что тогда она невозможна) $ cat Makefile shit: blah echo 1 blah: shit echo 2 $ make make: Warning: Infinite loop: Target `shit' depends on itself echo 2 2 echo 1 1 82. Кеширование файловых операций. Преимущества и недостатки. Отключение механизма кеширования. анонимный ананист: Вся суть кэширования: есть данные на некотором устройстве, к этим данным потенциально будут часто обращаться (разные процессы, один и тот же процесс, это не важно). Что бы каждый раз не осуществлять долгую операцию чтения с медленного устройства(диска, какого-либо носителя, типа памяти не важно) мы копируем потенциально необходимые данные на устройство обладающее большей скоростью. предварительно выделив на нем место под кэш. Когда некто запрашивает данные находящиеся в кэше для чтения ему их выдают из кэша, если запрос идёт на запись, то данные изменяются в кэше, и данному буферу присваивается статус загрязненного, что означает, перед тем, как сменить кэшируемую область данного буфера, данные из него необходимо слить в ту область которую он кэширует сейчас. (премоментно с буфером работает только один процесс(не важно чтение или запись(так написано, я б чтение не ограничивал)). Проблемс: система здохла раньше чем данные из буфера записали на диск. Были буферизованы данные которые использовали один раз(мы в место одной операции сделаем 2). Для оптимизации и быворки буферов на

Page 72: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

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

Так что касается отмены кэширования. Есть метод гарантированно не кэшировать : процесс может открыть файл в синхронном режиме(указав флаг O_SYNC в системном вызове open(2) При этом все изменения в файле будут немедленно сохраняться на диске. И два не отменяющих но будет чаще.

1)может использоваться системный вызов sync который обновляет все дисковые блоки, соответствующие "грязным" буферам. Необходимо отметить, что sync(2) не ожидает завершения операции ввода/вывода, таким образом после возврата из функции не гарантируется, что все "грязные" буферы сохранены на

2)Наконец, через регулярные промежутки времени в системе пробуждается специальный системный процесс — диспетчер буферного кэша (в различных версиях UNIX его названия отличаются, чаще всего используется fsflush или bdflush. Этот процесс освобождает "грязные" буферы, сохраняя их содержимое в соответствующих дисковых блоках.

83.Функция fcntl(2).Назначение, особенности использования. CP. int fcntl(int fildes, int cmd, /* arg*/ …); - предназначен для управления открытыми файлами.

Прототип: #include <sys/types.h> #include <unistd.h> #include <fcntl.h>

Аргументы: fildes – открытый файловый дескриптор, cmd – указывает выполнение какой команды необходимо. Также может принимать третий аргумент args в зависимости от команды (функция может принимать переменное количество аргументов). Возможные значения для cmd определены в <fcntl.h>. Возвращаемое значение. Код возврата интерпретируется в зависимости от команды! Как правило, в случае ошибки возвращает -1 и устанавливает соответствующее значение в переменную errno. Примеры команд и их функции. F_DUPFD / F_DUP2FD аналог dup/dup2 F_DUPFD

Возвращает новый файловый дескриптор с наименьшим доступным пронумерованным (тот, который не открыт) файловым дескриптором, больше или равный третьему аргументу, arg, взятому как целочисленный int. Новый файловый дескриптор ссылается на тот же открытй

Page 73: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

файловый дескриптор что и оригинальный файловый дескриптор и разделяет с ним любые блокировки. Флаг FD_CLOEXEC, ассоциированный с новым файловым дескриптором очищается, чтобы держать файл открытым для вызовов функций семейства exec(2).

F_DUP2FD

То же самое что и F_DUPFD, за исключением того что всегда возвоащает arg. F_DUPFD2 закрывает arg если он открыт и не равен fildes. Если fildes не равен arg, FD_CLOEXEC флаг, ассоциированный с новым файловым дескриптором очищается. Если fildes равен arg флаг FD_CLOEXEC, ассоциированный с новым файловым дескриптором не меняется.

F_FREESP освободить место Освободить место в памяти ассоциированное с секцией обычного файла fildes. Секция указывается

переменной типа struct flock, на которую указывает arg.

F_GETFD / F_SETFD флаг close on exec F_GETFD

Получить флаги, определенные в <fcntl.h>, файлового дескриптора fildes. Флаги только для одного

файлового дескриптора и не влияют на друие дескрипторы этого файла.

F_SETFD

Установить флаги, определенные в <fcntl.h>, файлового дескриптора fildes аргументу arg. Если

FD_CLOEXEC в третьем аргументе равен 0 файл будет открыт после выполнений exec, в противном случае закроется после первого удачного.

F_GETLK / F_SETLK F_GETLK

Получить первую блоировку которая блокирует дескиптор, на который указывает arg, указывающий на

struct flock. Полученная информация переписывается в указанный struct flock. Если блокировки нет, структура не будет изменена за исключением типа блокировки, который станет F_UNLCK.

F_SETLK

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

Флаги ниже. Если расшаренный или особый блокировка (вай дарагёй) не может быть установлена с помощью fcntl то вернется -1.

F_RDLCK / F_WRLCK / F_UNLCK Блокировки по чтению, записи, разблокировать. struct flock short l_type; /* lock operation type */

short l_whence; /* lock base indicator */

off_t l_start; /* starting offset from base */

off_t l_len; /* lock length; l_len == 0 means

until end of file */

Page 74: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

int l_sysid; /* system ID running process holding lock */

pid_t l_pid; /* process ID of process holding lock */

84. Маска создания файла. Функция umask(2), область применения. by iZoomko + manpages + SVR4 sources 2 байта информации. В SVR4 хранятся в области u (struct user:u_cmask) Эта маска применяется (как конъюнкция дополнения маски) к правам файла при создании файла процессом. Применяется для контроля безопасности существования создаваемых файлов. Так как по умолчанию это поле равно 0x0022, то при создании файла в любом случае только владелец будет иметь право изменять его. 85. Мультиплексирование ввода-вывода. Функции select(2) и poll(2). Читайте :3 Там есть чуть более, чем всё, что следует знать: https://scoecomp.files.wordpress.com/2014/02/2003-unix-network-programming-vol-1-3rd-ed.pdf Концепция мультиплексирования строится на передаче ответственности за начало ввода/вывода специализированным функциям, при этом освободив вызовы, отвечающие за непосредственный ввод/вывод. Это позволяет не блокироваться на одном вызове или делать сотню вызовов для опрашивания готовности устройства, а заблокироваться на функции, которая бы в цикле опрашивала дескрипторы. Мультиплексирование позволяет реализовать обработку нескольких дескрипторов, имитируя тем самым работу многопоточной программы в одном потоке.

● select Сигнатура:

int select( int nfds, fd_set_t *inset, fd_set_t *outset, fd_set_t *exset, struct timeval *tm );

Page 75: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

Если интересен пинуксовый вариант: http://lxr.free-electrons.com/source/fs/select.c nfds -- диапазон дескрипторов от 0 до nfds-1; inset -- множество дескрипторов на чтение. outset -- * на запись; exset -- *на проверку на наличие ошибок в дескрипторах; specifies the file descriptors to be checked for error conditions pending, and on output indicates which file descriptors have error conditions pending ( я не уметь корректно перевод ). Максимальное число дескрипторов зависит от системы; обычно 1024. tm -- таймаут опроса: NULL -- вечное ожидание, != 0 -- в миллисекундах, 0 -- не ждать; если задать большое число, то, скорее всего, select вам скажет: ``EINVAL’’. Для установки множеств используются МАКРОСЫ: void FD_CLR(int fd, fd_set *set);

Удалить дескриптор. void FD_SET(int fd, fd_set *set);

Добавить дискриптор. int FD_ISSET(int fd, fd_set *set);

Проверка наличия fd в множестве. void FD_ZERO(fd_set *set);

Очистка. Существует вариация select -- pselect. Отличия в том, что pselect a) отсчитывает время в секундах/наносекундах, b) не обновляет своё время (???), c) устанавливает на время работы маску сигналов, переданную в качестве аргумента. С использованием select в многопоточной программе возникают неопределённые неоднозначности. Готовность дескрипторов.

1. Число байт в буфере ( сокета ) больше или равно low-water-mark. 2. Закрытие дескриптора на другом конце ( сокеты, пайпы ). 3. Ошибка.

● poll:

int poll( struct pollfds *ufds, int ndfs, int timeout ); /* 8 bytes. */ struct pollfds {

int fds; /* Твой тостер. */ short events; /* Просматриваемые события; если несколько, побитовое ИЛИ. */ short revents; /* Произошедшие события; если несколько, побитовое ИЛИ. */

}; События представляются константами: POLLIN, POLLOUT, POLLPRI ( out-of-band data ). Очевидно, могут присутствовать дополнения. VS: С одной стороны, select проверяет *каждый* дескриптор из диапазона, что, при максимальном ( ~ 1024 ) количестве дескрипторов достаточно много, с другой -- копирование из разных спейсов данных с 8 байтами на дескриптор тоже занятие жЫрное.

Page 76: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

From Richard Stevens ([email protected]): The basic difference is that select()'s fd_set is a bit mask and therefore has some fixed size. It would be possible for the kernel to not limit this size when the kernel is compiled, allowing the application to define FD_SETSIZE to whatever it wants (as the comments in the system header imply today) but it takes more work. 4.4BSD's kernel and the Solaris library function both have this limit. But I see that BSD/OS 2.1 has now been coded to avoid this limit, so it's doable, just a small matter of programming. :-) Someone should file a Solaris bug report on this, and see if it ever gets fixed. With poll(), however, the user must allocate an array of pollfd structures, and pass the number of entries in this array, so there's no fundamental limit. As Casper notes, fewer systems have poll() than select, so the latter is more portable. Also, with original implementations (SVR3) you could not set the descriptor to -1 to tell the kernel to ignore an entry in the pollfd structure, which made it hard to remove entries from the array; SVR4 gets around this. Personally, I always use select() and rarely poll(), because I port my code to BSD environments too. Someone could write an implementation of poll() that uses select(), for these environments, but I've never seen one. Both select() and poll() are being standardized by POSIX 1003.1g. https://daniel.haxx.se/docs/poll-vs-select.html Работа с текстом в vi/emacs на выбор экзаменуемого:

● создание, открытие и закрытие файла; ● навигация и поиск по тексту; ● управление положением курсора; ● копирование, вставка и замена текста.

Page 77: О т в е т ы на э к за м е н по СП О . 2 0 1 6 гкзамен... · Ричард Миллер (канадец, работавший в Австралии) смог

Задачи: Есть комната с игровым автоматом на два человека. Необходимо реализовать на средствах синхронизации потоков схему, при которой в зал входило и выходило две разные пары людей ( если оба человека не вышли, новые не заходят ). я не понял, как работает