- Linux управление системным по
- Информация о состоянии системных служб
- Запуск и остановка системных служб
- Активация и деактивация системных служб
- Совместное использование подкоманд для активации и запуска системных служб
- Множество подкоманд и полезный механизм для получения их списка
- Заключение
- Изучаем процессы в Linux
- Содержание
- Введение
- Атрибуты процесса
- Жизненный цикл процесса
- Рождение процесса
- Состояние «готов»
- Состояние «выполняется»
- Перерождение в другую программу
- Состояние «ожидает»
- Состояние «остановлен»
- Завершение процесса
- Состояние «зомби»
- Забытье
- Благодарности
Linux управление системным по
Управление системными службами чаще всего осуществляется системными администраторами, но иногда должно осуществляться и обычными пользователями. Без сомнения, замена SysV (команды service и chkconfig) на systemd (команда systemctl) вызвала достаточно неоднозначную реакцию пользователей и администраторов. В результате у обоих систем остались свои приверженцы.
На сегодняшний день подавляющее большинство дистрибутивов использует systemd для управления системными службами. По этой причине стоит уметь пользоваться командой systemctl.
Я не считаю, что каждый из пользователей может самостоятельно разобраться со всеми нюансами использования рассматриваемого инструментария. По этой причине я постараюсь объяснить все нюансы, связанные с командой systemctl, максимально простыми словами. В конце будет подведены итоги и даны советы по использованию тех или иных подкоманд.
Примечание: на man-странице systemctl первым параметром является «команда», что может смутить неискушенного пользователя. Я буду называть командой саму команду systemctl, а ее первый параметр — подкомандой. Вторым параметром команды является имя системной службы.
# systemctl подкоманда системная-служба
В качестве примера я буду использовать службу cron:
# systemctl status cron
Информация о состоянии системных служб
При диагностике работы системы следует начинать с получения информации о состоянии важных системных служб. Самым простым решением данной задачи является использование подкоманды status:
# systemctl status cron
● cron.service — Regular background program processing daemon
Loaded: loaded (/lib/systemd/system/cron.service; enabled; vendor preset: enabled)
Active: active (running) since Thu 2020-10-29 17:37:29 MSK; 1h 35min ago
Docs: man:cron(8)
Main PID: 915 (cron)
Tasks: 1 (limit: 4612)
Memory: 2.9M
CGroup: /system.slice/cron.service
└─915 /usr/sbin/cron -f
окт 29 18:17:02 layla CRON[5644]: pam_unix(cron:session): session closed for user root
окт 29 18:30:01 layla CRON[7293]: pam_unix(cron:session): session opened for user root by (uid=0)
.
Разумеется, вы можете использовать другие имена системных служб, которые можно получить с помощью команды:
# systemctl —no-pager | grep service
Обратите внимание на количество дополнительной информации о службе: описание, путь к service-файлу и время загрузки, состояние идентификатор процесса (PID), а также диагностические сообщения.
Команда systemctl status также весьма полезна для выяснения причин неработоспособности тех или иных системных механизмов. При диагностике систем я первым делом проверяю состояние основных системных служб с помощью systemctl. Зачем беспокоится о межсетевых экранах, SELinux/Apparmor или файлах конфигурации, если необходимая служба даже не запущена?
Что же, теперь вы знаете, как получить информацию о состоянии системной службы, такой, как cron. Но как изменить само это состояние?
Запуск и остановка системных служб
При изменении файла конфигурации той или иной запущенной системной службы, вам придется либо перезапустить саму службу, либо перезагрузить ее конфигурацию. В результате служба повторно прочитает содержимое файла конфигурации и изменит свое поведение в соответствии с ним. В прошлом для этой цели использовалась команда service:
# service cron restart
В случае systemd для этой цели используется команда systemctl. К примеру, для перезапуска системной службы cron с помощью systemctl следует выполнить следующую команду:
# systemctl restart cron
На мой взгляд, данный синтаксис более очевиден. Для того, чтобы остановить или запустить системную службу, следует использовать соответствующий синтаксис и подкоманды stop и start соответственно, например:
# systemctl stop cron
# systemctl start cron
Службы, которые не прекращают работу после использования подкоманды stop, могут быть остановлены принудительно с помощью подкоманды kill. Например, для принудительной остановки службы cron следует использовать следующую команду:
# systemctl kill cron
Перезагрузка конфигурации системной службы работает немного по-другому. Подкоманда reload просто сообщает системной службе о необходимости повторного чтения содержимого файла конфигурации, в отличие от команды restart, которая останавливает и снова запускает ее, в результате чего также читается обновленное содержимое файла конфигурации.
Например, если вы используете команду systemctl restart cron, планировщик будет полностью перезапущен. В то же время, при перезагрузке конфигурации ему будет отправлен соответствующий сигнал. В обоих случаях обновленное содержимое файла конфигурации будет прочитано и учтено.
Перезагрузка конфигурации осуществляется гораздо быстрее, но не все службы поддерживают ее.
Подкоманды start, stop, restart и reload оказывают влияние лишь на текущую рабочую сессию.
Активация и деактивация системных служб
Многие системные администраторы, мало знакомые с Linux, не понимают разницы между подкомандами start/stop и enable/disable. Я уже рассказывал о командах start, stop и restart в предыдущем разделе.
Подкоманды start и stop изменяют текущее состояние службы. Однако, после перезагрузки системы ее состояние будет приведено к тому, которое было установлено по умолчанию. Другими словами, если я остановлю службу cron и перезагружу компьютер, в процессе его загрузки она будет снова запущена.
В прошлом вы наверняка использовали команду chkconfig для установки уровней исполнения для запуска и остановки тех или иных служб. Например:
# chkconfig —level 35 cron on
Эта команда активирует запуск службы cron на уровнях исполнения 3 и 5.
В случае с systemctl активация запуска служб осуществляется с помощью подкоманд enable и disable. Синтаксис соответствующих команд аналогичен синтаксису команд с подкомандами start, stop и restart.
Например, для активации запуска службы cron в процессе загрузки системы может использоваться следующая команда:
# systemctl enable cron
Аналогично, для деактивации запуска этой службы в процессе загрузки системы может использоваться следующая команда:
# systemctl disable cron
Активация и деактивация системных служб, по аналогии с их запуском и остановкой, обычно не вызывает каких-либо вопросов. Однако, вопросы появляются в случае необходимости использования обоих классов подкоманд.
Совместное использование подкоманд для активации и запуска системных служб
Некоторым системным администраторам и пользователям может показаться странным то, что подкоманда активации системной службы не запускает ее. Например, если вы установили системную программу и хотите запустить ее для тестирования работоспособности, после чего хотите активировать ее запуск в процессе загрузки системы, вам придется выполнить две команды:
# systemctl start cron
# systemctl enable cron
Synchronizing state of cron.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable cron
Created symlink /etc/systemd/system/multi-user.target.wants/cron.service → /lib/systemd/system/cron.service.
Деактивация системной службы осуществляется по аналогичной схеме. Вам придется использовать подкоманду disable для деактивации запуска службы в процессе загрузки системы. Однако, в том случае, если служба уже запущена, вам придется использовать подкоманду stop для завершения ее работы.
Например, деактивация и остановка службы cron могут быть осуществлены с помощью следующих команд:
# systemctl stop cron
# systemctl disable cron
Synchronizing state of cron.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install disable cron
Removed /etc/systemd/system/multi-user.target.wants/cron.service.
Не забывайте о том, что вы всегда можете воспользоваться подкомандой status, если не уверены в корректности выполненных действий:
# systemctl status cron
Для того, чтобы убедиться в том, что запуск службы при загрузке системы активрован, вы можете воспользоваться еще одной подкомандой systemctl под названием is-enabled. Например, для проверки статуса активации службы cron следует использовать следующую команду:
# systemctl is-enabled cron
enabled
Множество подкоманд и полезный механизм для получения их списка
Я рассказал о некоторых подкомандах systemctl, таких, как start, stop, restart, enable, disable, status и некоторых других. Их уже достаточно для того, чтобы запутаться! Если вы используете Fedora Workstation, то вам поможет старый друг — клавиша Tab, используемая для автозавершения команд. Попробуйте сделать следующее: введите команду systemctl и символ пробела после нее. После этого дважды нажмите клавишу Tab, в результате чего должен быть выведен полный список подкоманд команды systemctl. Не уверен, что большинство системных администраторов и пользователей знают о данном механизме.
Заключение
Как вы убедились сами, управление системными службами с помощью утилиты systemctl не представляет каких-либо сложностей. Мне кажется, что она работает более логично, чем такие утилиты, как service и chkconfig. Кроме того, использование одной команды для управления службами вместо двух гораздо удобнее.
Вам следует запомнить следующие правила:
- Для управления текущим состоянием служб следует использовать подкоманды start/stop/restart
- После модификации файлов конфигурации системных служб следует использовать подкоманды start/stop/restart/reload
- Для активации и деактивации запуска системных служб в процессе загрузки системы следует использовать подкоманды enable/disable
- В процессе диагностики системы следует использовать подкоманду status на раннем этапе
Наконец, вам не придется запоминать все подкоманды systemctl. Вы можете либо просто ввести systemctl, символ пробела и дважды нажать Tab, либо воспользоваться командой systemctl —help, если первый вариант не срабатывает.
Управление системными службами осуществляется как в процессе администрирования мощных серверов, так и в процессе администрирования домашних систем и я надеюсь, что теперь вам будет немного проще работать с командой systemctl и ее подкомандами.
Источник
Изучаем процессы в Linux
В этой статье я хотел бы рассказать о том, какой жизненный путь проходят процессы в семействе ОС Linux. В теории и на примерах я рассмотрю как процессы рождаются и умирают, немного расскажу о механике системных вызовов и сигналов.
Данная статья в большей мере рассчитана на новичков в системном программировании и тех, кто просто хочет узнать немного больше о том, как работают процессы в Linux.
Всё написанное ниже справедливо к Debian Linux с ядром 4.15.0.
Содержание
Введение
Системное программное обеспечение взаимодействует с ядром системы посредством специальных функций — системных вызовов. В редких случаях существует альтернативный API, например, procfs или sysfs, выполненные в виде виртуальных файловых систем.
Атрибуты процесса
Процесс в ядре представляется просто как структура с множеством полей (определение структуры можно прочитать здесь).
Но так как статья посвящена системному программированию, а не разработке ядра, то несколько абстрагируемся и просто акцентируем внимание на важных для нас полях процесса:
- Идентификатор процесса (pid)
- Открытые файловые дескрипторы (fd)
- Обработчики сигналов (signal handler)
- Текущий рабочий каталог (cwd)
- Переменные окружения (environ)
- Код возврата
Жизненный цикл процесса
Рождение процесса
Только один процесс в системе рождается особенным способом — init — он порождается непосредственно ядром. Все остальные процессы появляются путём дублирования текущего процесса с помощью системного вызова fork(2) . После выполнения fork(2) получаем два практически идентичных процесса за исключением следующих пунктов:
- fork(2) возвращает родителю PID ребёнка, ребёнку возвращается 0;
- У ребёнка меняется PPID (Parent Process Id) на PID родителя.
После выполнения fork(2) все ресурсы дочернего процесса — это копия ресурсов родителя. Копировать процесс со всеми выделенными страницами памяти — дело дорогое, поэтому в ядре Linux используется технология Copy-On-Write.
Все страницы памяти родителя помечаются как read-only и становятся доступны и родителю, и ребёнку. Как только один из процессов изменяет данные на определённой странице, эта страница не изменяется, а копируется и изменяется уже копия. Оригинал при этом «отвязывается» от данного процесса. Как только read-only оригинал остаётся «привязанным» к одному процессу, странице вновь назначается статус read-write.
Состояние «готов»
Сразу после выполнения fork(2) переходит в состояние «готов».
Фактически, процесс стоит в очереди и ждёт, когда планировщик (scheduler) в ядре даст процессу выполняться на процессоре.
Состояние «выполняется»
Как только планировщик поставил процесс на выполнение, началось состояние «выполняется». Процесс может выполняться весь предложенный промежуток (квант) времени, а может уступить место другим процессам, воспользовавшись системным вывозом sched_yield .
Перерождение в другую программу
В некоторых программах реализована логика, в которой родительский процесс создает дочерний для решения какой-либо задачи. Ребёнок в данном случае решает какую-то конкретную проблему, а родитель лишь делегирует своим детям задачи. Например, веб-сервер при входящем подключении создаёт ребёнка и передаёт обработку подключения ему.
Однако, если нужно запустить другую программу, то необходимо прибегнуть к системному вызову execve(2) :
или библиотечным вызовам execl(3), execlp(3), execle(3), execv(3), execvp(3), execvpe(3) :
Все из перечисленных вызовов выполняют программу, путь до которой указан в первом аргументе. В случае успеха управление передаётся загруженной программе и в исходную уже не возвращается. При этом у загруженной программы остаются все поля структуры процесса, кроме файловых дескрипторов, помеченных как O_CLOEXEC , они закроются.
Как не путаться во всех этих вызовах и выбирать нужный? Достаточно постичь логику именования:
- Все вызовы начинаются с exec
- Пятая буква определяет вид передачи аргументов:
- l обозначает list, все параметры передаются как arg1, arg2, . NULL
- v обозначает vector, все параметры передаются в нуль-терминированном массиве;
- Далее может следовать буква p, которая обозначает path. Если аргумент file начинается с символа, отличного от «/», то указанный file ищется в каталогах, перечисленных в переменной окружения PATH
- Последней может быть буква e, обозначающая environ. В таких вызовах последним аргументом идёт нуль-терминированный массив нуль-терминированных строк вида key=value — переменные окружения, которые будут переданы новой программе.
Семейство вызовов exec* позволяет запускать скрипты с правами на исполнение и начинающиеся с последовательности шебанг (#!).
Есть соглашение, которое подразумевает, что argv[0] совпадает с нулевым аргументов для функций семейства exec*. Однако, это можно нарушить.
Любопытный читатель может заметить, что в сигнатуре функции int main(int argc, char* argv[]) есть число — количество аргументов, но в семействе функций exec* ничего такого не передаётся. Почему? Потому что при запуске программы управление передаётся не сразу в main. Перед этим выполняются некоторые действия, определённые glibc, в том числе подсчёт argc.
Состояние «ожидает»
Некоторые системные вызовы могут выполняться долго, например, ввод-вывод. В таких случаях процесс переходит в состояние «ожидает». Как только системный вызов будет выполнен, ядро переведёт процесс в состояние «готов».
В Linux так же существует состояние «ожидает», в котором процесс не реагирует на сигналы прерывания. В этом состоянии процесс становится «неубиваемым», а все пришедшие сигналы встают в очередь до тех пор, пока процесс не выйдет из этого состояния.
Ядро само выбирает, в какое из состояний перевести процесс. Чаще всего в состояние «ожидает (без прерываний)» попадают процессы, которые запрашивают ввод-вывод. Особенно заметно это при использовании удалённого диска (NFS) с не очень быстрым интернетом.
Состояние «остановлен»
В любой момент можно приостановить выполнение процесса, отправив ему сигнал SIGSTOP. Процесс перейдёт в состояние «остановлен» и будет находиться там до тех пор, пока ему не придёт сигнал продолжать работу (SIGCONT) или умереть (SIGKILL). Остальные сигналы будут поставлены в очередь.
Завершение процесса
Ни одна программа не умеет завершаться сама. Они могут лишь попросить систему об этом с помощью системного вызова _exit или быть завершенными системой из-за ошибки. Даже когда возвращаешь число из main() , всё равно неявно вызывается _exit .
Хотя аргумент системного вызова принимает значение типа int, в качестве кода возврата берется лишь младший байт числа.
Состояние «зомби»
Сразу после того, как процесс завершился (неважно, корректно или нет), ядро записывает информацию о том, как завершился процесс и переводит его в состояние «зомби». Иными словами, зомби — это завершившийся процесс, но память о нём всё ещё хранится в ядре.
Более того, это второе состояние, в котором процесс может смело игнорировать сигнал SIGKILL, ведь что мертво не может умереть ещё раз.
Забытье
Код возврата и причина завершения процесса всё ещё хранится в ядре и её нужно оттуда забрать. Для этого можно воспользоваться соответствующими системными вызовами:
Вся информация о завершении процесса влезает в тип данных int. Для получения кода возврата и причины завершения программы используются макросы, описанные в man-странице waitpid(2) .
Передача argv[0] как NULL приводит к падению.
Бывают случаи, при которых родитель завершается раньше, чем ребёнок. В таких случаях родителем ребёнка станет init и он применит вызов wait(2) , когда придёт время.
После того, как родитель забрал информацию о смерти ребёнка, ядро стирает всю информацию о ребёнке, чтобы на его место вскоре пришёл другой процесс.
Благодарности
Спасибо Саше «Al» за редактуру и помощь в оформлении;
Спасибо Саше «Reisse» за понятные ответы на сложные вопросы.
Они стойко перенесли напавшее на меня вдохновение и напавший на них шквал моих вопросов.
Источник