Введение

MacOS фреймворк управления системными службами

launchd — это демон инициализации и управления службами операционной системы, разработанный Apple Inc. в составе macOS для замены init в стиле BSD и SystemStarter. Предпринимались попытки портировать launchd на FreeBSD и производные от неё системы.

Компоненты

В системе launchd существуют две основные программы: launchd и launchctl. launchd управляет демонами как на уровне системы, так и на уровне пользователя. Подобно xinetd, launchd может запускать демоны по требованию. Как и watchdogd, launchd может отслеживать демоны, чтобы убедиться, что они продолжают работать. launchd также заменил init в качестве PID 1 в macOS и, следовательно, отвечает за запуск системы при загрузке. Параметры служб, запускаемых launchd, определяются в конфигурационных файлах. Эти файлы, хранящиеся в подкаталогах LaunchAgents и LaunchDaemons папок Library, представляют собой списки свойств и содержат около тридцати различных ключей, которые можно настроить. Сам launchd не имеет доступа к этим конфигурационным файлам и не может их читать – это задача "launchctl". launchctl – это командная утилита, которая взаимодействует с launchd посредством IPC и умеет разбирать файлы списков свойств, используемые для описания заданий launchd, сериализуя их с помощью специализированного протокола словаря, понятного launchd. launchctl можно использовать для загрузки и выгрузки демонов, запуска и остановки заданий, управляемых launchd, получения статистики использования системы для launchd и его дочерних процессов, а также для установки переменных окружения.

Запуск

У launchd две основные задачи. Первая — загрузка системы, вторая — загрузка и обслуживание сервисов. Вот упрощенный обзор запуска системы Mac OS X Tiger на PowerPC Mac (на Intel Mac EFI заменяет Open Firmware, а boot.efi заменяет BootX): Open Firmware активируется, инициализирует аппаратное обеспечение, а затем загружает BootX. BootX загружает ядро, отображает спиннер (курсор в виде шестеренки) и загружает необходимые расширения ядра (kexts). Ядро загружает launchd. Launchd запускает /etc/rc, различные скрипты, которые сканируют каталоги /System/Library/LaunchDaemons и /Library/LaunchDaemons, вызывая launchctl для plist-файлов по мере необходимости, а затем launchd запускает окно входа в систему. На шаге 4 скрипты запуска сканируют несколько различных каталогов в поисках заданий для выполнения. Сканируются два различных каталога: каталоги LaunchDaemons содержат элементы, которые будут выполняться от имени root, как правило, фоновые процессы. Каталоги LaunchAgents содержат задания, называемые агентскими приложениями, которые будут выполняться от имени пользователя или в контексте пользовательского пространства. Это могут быть скрипты или другие приложения переднего плана, и они могут даже включать пользовательский интерфейс. Все эти каталоги хранятся в стандартных каталогах Library в Mac OS X.

Launchd сильно отличается от SystemStarter тем, что он может не запускать все демоны во время загрузки. Ключевая особенность launchd, схожая с xinetd, — это идея запуска демонов по требованию. Когда launchctl сканирует plist-файлы заданий во время загрузки, он просит launchd зарезервировать и прослушивать все порты, запрошенные этими заданиями. Если в plist-файле указан ключ "OnDemand", демон фактически не загружается в этот момент. Вместо этого launchd прослушивает порт, запускает демон при необходимости и завершает его работу, когда он больше не нужен. После загрузки демона launchd отслеживает его и обеспечивает его работу, если это необходимо. Таким образом, он похож на watchdogd и разделяет требование watchdogd о том, что процессы не должны самостоятельно создавать дочерние процессы или становиться демонами. Если процесс переходит в фоновый режим, launchd теряет его из виду и пытается перезапустить. Следовательно, Mac OS X Tiger загружается намного быстрее, чем предыдущие версии. Система должна только зарегистрировать демоны, которые необходимо запустить, и не запускает их, пока они не понадобятся. Фактически, панель прогресса, которая появляется во время загрузки, — это просто приложение-заглушка (называемое WaitingForLoginWindow), которое на самом деле не показывает ничего, кроме течения времени. Самой сложной задачей при управлении загрузкой launchd являются зависимости. SystemStarter имел очень простую систему зависимостей, которая использовала ключи "Uses", "Requires" и "Provides" в plist-файле элемента запуска. Существует две основные стратегии при создании зависимостей launchd в Tiger: IPC позволяет демонам общаться друг с другом для разрешения зависимостей, или демоны могут отслеживать изменения файлов или путей. Использование IPC намного сложнее, чем ключи SystemStarter, и требует больше работы от разработчика, но может привести к более чистому и быстрому запуску. SystemStarter поддерживался до OS X Mountain Lion, но был удален в OS X Yosemite.

Запуск

В launchd управление службами централизовано в приложении launchctl. Сам по себе launchctl может принимать команды из командной строки, из стандартного ввода или работать в интерактивном режиме. С правами суперпользователя launchctl можно использовать для внесения изменений в глобальном масштабе. Набор команд launchctl можно сделать постоянным, сохранив их в файле /etc/launchd.conf. (Файл ~/.launchd.conf для каждого пользователя рассматривался, но не поддерживается ни в одной существующей версии macOS.) launchctl взаимодействует с launchd посредством специфического для Mach механизма межпроцессного взаимодействия (IPC).

Протокол активации сокета

Имя каждого ключа в разделе Sockets будет помещено в окружение задачи при её запуске, а файловый дескриптор этого сокета станет доступен в этой переменной окружения. Это отличается от активации сокетов systemd тем, что имя определения сокета внутри конфигурации задачи жёстко прописано в приложении. Этот протокол менее гибок, хотя и не требует, как systemd, чтобы демон жёстко кодировал начальный файловый дескриптор (по состоянию на 2014 год, это был дескриптор 3).

История выпусков Apple с открытым исходным кодом

Версия Лицензия Включено в версии macOS Включено версии Apple Developer Tools launchd 106 Лицензия Apple Public Source launchd 106.3 Лицензия Apple Public Source launchd 106.10 Лицензия Apple Public Source launchd 106.13 Лицензия Apple Public Source launchd 106.14 Лицензия Apple Public Source launchd 106.20 Лицензия Apple Public Source launchd 152 Лицензия Apache 2.0 launchd 257 Лицензия Apache 2.0 launchd 258.1 Лицензия Apache 2.0 launchd 258.12 Лицензия Apache 2.0 launchd 258.18 Лицензия Apache 2.0 launchd 258.19 Лицензия Apache 2.0 launchd 258.22 Лицензия Apache 2.0 launchd 258.25 Лицензия Apache 2.0 launchd 328 Лицензия Apache 2.0 launchd 329.3 Лицензия Apache 2.0 launchd 329.3.1 Лицензия Apache 2.0 launchd 329.3.2 Лицензия Apache 2.0 launchd 329.3.3 Лицензия Apache 2.0 launchd 392.18 Лицензия Apache 2.0 launchd 392.35 Лицензия Apache 2.0 launchd 392.36 Лицензия Apache 2.0 launchd 392.38 Лицензия Apache 2.0 launchd 392.39 Лицензия Apache 2.0 launchd 442.21 Лицензия Apache 2.0 launchd 442.26.2 Лицензия Apache 2.0 launchd 842.1.4 Лицензия Apache 2.0 launchd 842.90.1 Лицензия Apache 2.0 launchd 842.92.1 Лицензия Apache 2.0