Ядро Linux

Ядро Linux

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

Описание изображения

Для начала, ядро - это программа. В отличии от других программ, оно лежит в директории /boot и называется vmlinuz:

ls /boot

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

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

uname -r

Давайте посмотрим, сколько же весит ядро: для этого воспользуемся утилитой:

du -h vmlinuz* Описание изображения

Как видите, ядро весит почти 11 мегабайт. На самом деле, буква z в слове vmlinuz говорит о том, что ядро сжато. То есть, фактически, оно весит чуть больше.

Вы уже знаете – ядро Linux используется везде: android смартфоны, коих больше 3 миллиардов, работают на Linux; огромное количество сетевого оборудования, серверов, умных телевизоров, холодильников, машин, да даже бортовые компьютеры Space X – всё это работает на Linux. Это огромное количество разнообразного оборудования, которое должно поддерживать ядро. Поэтому в разработке ядра участвуют тысячи крупнейших компаний и специалистов. И всё ради 11 мегабайтного файла? Конечно нет. В этом файле только основной функционал, необходимый для работы – работа с памятью, управление процессам. Когда же ядру нужен дополнительный функционал – допустим, чтобы работать с сетевым адаптером, видеокартой или другим оборудованием – ядро обращается к специальным файлам, называемым модулями. В модулях хранится код, необходимый для работы с оборудованием или программный функционал – допустим, драйвер для видеокарты или программа для шифрования. Обычно это происходит незаметно для пользователя – вы вставили флешку, а ядро загрузило модуль для работы с usb флешками, а также модуль для работы с файловой системой на этой флешке. На других операционных системах это может работать по другому – есть различные архитектуры ядер операционных систем. У Linux архитектура модульная – то есть какой-то функционал вынесен в модули и подгружается по необходимости. Также Linux называют монолитным – потому что всё что делает ядро происходит в рамках одной программы – а правильнее сказать – все части ядра работают в одном адресном пространстве. Но так как у Linux-а огромный функционал, который бессмысленно держать одновременно в памяти – поэтому функционал вынесен в модули, благодаря чему ускоряется работа ядра.

Так вот, модули ядра хранятся в директории /lib/modules/:

ls /lib/modules* Описание изображения

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

И так, для управления модулями ядра используется утилита:

modprobe

Допустим, если хотим загрузить модуль radeon, пишем:

sudo modprobe radeon

Увидеть можем с помощью утилиты lsmod, которая показывает загруженные модули:

lsmod | grep radeon Описание изображения

Одни модули могут работать с другими и сами могут использоваться какими-то процессами. Например, чтобы выгрузить модуль из ядра, можно использовать тот же modprobe с ключом -r:

sudo modprobe -r radeon Описание изображения

Этот модуль не использовался, поэтому мне получилось с лёгкостью его выгрузить. Но есть модуль, допустим, vboxguest, который используется и убрать его с помощью modprobe не получится:

sudo modprobe -r parsec Описание изображения

Процессы, системные вызовы и прерывания

Как мы с вами знаем, каждая программа на компьютере хранится на диске системы - SSD или HDD. Когда мы запускаем программу, она загружается в оперативную память, так как скорость чтения с жёсткого диска или даже ssd относительно низкая, а процессор работает на больших скоростях и процессору намного быстрее добраться до оперативной памяти. Как правило, большие программы загружаются в оперативную память не полностью, а по мере необходимости. При этом, для каждой программы создаётся иллюзия, что она – единственная в оперативной памяти, то есть для неё создаётся так называемая «виртуальная память». Также программы при запуске загружают какие-то файлы, будь то файлы настроек или пользовательские файлы – как например, если мы запускаем nano file, то в память загружаются как сам /usr/bin/nano, его настройки - /etc/nanorc и ~/.nanorc, различные библиотеки, необходимые для работы nano и сам файл, который мы открываем. Кроме этого также запускаемой программе передаются переменные окружения операционной системы. Выполняя задачу, каждая программа использует процессорные мощности для выполнения своей работы. И совокупность всего этого называется процессом.

И так, выполняемая программа – это процесс. Начнём с того, что администратору важно видеть список процессов. Для этого есть несколько способов, начнём с утилиты ps. Если просто запустить:

ps Описание изображения

Мы увидим список процессов, запущенных в этом терминале. Как вы заметили, вывелось 4 строчки – bash и ps, в основном. При том, что ps у нас выполнился за какие-то доли секунды, он у нас всё равно виден в выводе – потому что он делает скриншот процессов именно в момент выполнения, поэтому и видит сам себя.

Но ведь не значит это, что на компьютере работает только 4 процесса? Как узнать больше информации?

ps -ef Описание изображения

Давайте разберём, что означают ключи и как читать вывод. Ключ -e выводит все процессы всех пользователей:

ps -e

Да, процессы запускаются от имени пользователей. От этого зависит какие права будут у процесса. Допустим, если я запускаю программу nano от пользователя user, то программа сможет работать с моими файлами. А ключ f, в расширенном формате выводит информацию по процессу:

Первое – UID – user id - пользователь, который запустил процесс. Большинство процессов в системе запущены от пользователя root.

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

Третий столбик – PPID – parent process id – идентификатор родительского процесса. Почти все процессы в системе были запущены каким-то другим процессом. Допустим, когда мы запускаем эмулятор терминала, а в нём nano – то родительским процессом для nano является bash, который запущен в этом эмуляторе терминала.

Обычно процессы появляются, делают свою работу и завершаются не требуя никакого внимания. Но бывают случаи, когда администратору все же следует вмешаться. Давайте разберём пару таких ситуаций. Самая популярная – зависание процесса или системы. Я думаю все сталкивались с такими ситуациями, когда какой-то процесс начинает использовать слишком много оперативной памяти или ресурсов процессора. Это приводит к тому, что каким-то другим процессам, той же оболочке, перестаёт хватать ресурсов и всё начинает зависать. Чтобы решить проблему, сначала нужно понять, какой процесс во всём виноват. Для этого нужно увидеть список процессов, которые используют большую часть ресурсов. Это нам покажет утилита top:

top Описание изображения

Наверху отображается общая информация по системе. Давайте пройдёмся по каждому из значений. Первая строчка – вывод утилиты uptime:

  • Текущее время в системе
  • Сколько времени система включена
  • Хоть тут и написано user, подразумевается количество авторизованных сессий. Это могут быть как сессии одного пользователя, так и других
  • Далее, "load average" - Среднее значение загрузки системы за минуту, 5 минут и 15 минут. Есть свои нюансы подсчёта этого значения.

    Описание изображения

    На второй строчке информация о количестве процессов:

  • Сколько всего запущенных процессов
  • Сколько процессов выполняется в данный момент
  • Сколько процессов просто спят, например, в ожидании каких-то данных
  • Сколько процессов остановлены, но до сих пор находятся в оперативной памяти и ожидают ручной активации каким-то процессом или администратором
  • Сколько зомби процессов. Когда один процесс запускает другой, то он является для него родительским процессом, а запущенный – дочерним. Так вот, когда дочерний процесс выполнит свою задачу, он завершается, отправляя отчет о работе к родительскому процессу. В случае, если родительский процесс из-за ошибки разработчика или другой причины не завершает процесс, а оставляет его в фоновом режиме, то такой процесс называется зомби. Зомби процессы занимают лишнее пространство и бессмысленно тратят ресурсы компьютера.
  • Сервисный менеджер Systemd

    systemd, как сервисный менеджер, позволяет управлять этими сервисами. Для примера возьмём сервис под названием sshd. Вы часто будете встречать сервисы с буквой d в конце - она означает daemon, то есть демон программы ssh. Базовые операции - это остановить, запустить и перезапустить сервис - то есть:

  • sudo systemctl stop sshd
  • sudo systemctl start sshd
  • sudo systemctl restart sshd
  • соответственно. Как понятно из названия, restart останавливает и запускает сервис заново. Обычно перезапускают сервис, когда изменяются какие-то настройки демона. Нужно его заново запустить, чтобы он перечитал свои настройки. Для каких-то сервисов это не проблема, но бывают важные сервисы, в которых даже секундная остановка вызывает проблемы. Для таких сервисов существует возможность перезапустить основной демон, при этом не затронув текущие процессы. Для этого используется опция reload

  • sudo systemctl reload sshd
  • Мы можем добавить в автозагрузку любой сервис, чтобы он автоматически включался при запуске компьютера

  • systemctl enable sshd
  • А отменить автозагрузку можно так:

  • systemctl disable sshd
  • А можно получить информацию о статусе процесса?

  • systemctl status sshd
  • Описание изображения

    В строчке Loaded мы видим путь до основного файла сервиса. Дальше 2 раза видим слово enabled. Первый enabled говорит о том, что сервис включён, т.е., он будет запускаться при включении компьютера. Перед вторым enabled написано vendor preset. То есть, имеется в виду, что этот сервис был включён по умолчанию ещё при установке программы или операционной системы

    В строчке Active мы видим, что сервис не работает. Если остановить сервис, здесь будет писаться inactive.

    Описание изображения

    Или наборот, статус Active с зеленым вариантом, тут мы сделаем вывод, что все в порядке и сервис работает корректно