Как насчет runit
, "UNIX init схема с сервисным контролем"?
Я думаю, что это соответствует Вашим требованиям, т.е.
sv status service
lighttpd
страница Wiki на runit
, см. также эти сценарии выполнения включая lighttpd
и mongodb
)Я не могу ответить на "один сервис в некоторых вариантах" проблема умным способом, Вы могли, конечно, определить сервисы отдельно... (мог бы быть некоторый аккуратный symlink-and-examine-my-pwd-solution к этому, но я не уверен при попытке быть умной вот хорошая идея; размышление о пригодности для обслуживания)
Страница This ArchWiki редактирования предоставляет быстрый обзор, который мог бы быть лучшим запуском, чем runit
страница.
Системные вызовы сами по себе являются концепцией. Они представляют действия, которые процессы могут запрашивать у ядра.
Эти системные вызовы реализованы в ядре UNIX-подобной системы. Эта реализация (написанная на C и на asm для небольших частей) фактически выполняет действие в системе.
Затем процессы используют интерфейс, чтобы запросить у системы выполнение системных вызовов. Этот интерфейс указан в POSIX. Это набор функций стандартной библиотеки C. На самом деле они являются оболочками, они могут выполнять некоторые проверки, а затем вызывать в ядре специфичную для системы функцию, которая сообщает ему о выполнении действий, требуемых системным вызовом.А уловка в том, что те функции, которые являются интерфейсом, называются так же, как и сами системные вызовы, и часто называются «системными вызовами».
Вы можете вызвать функцию в ядре, которая выполняет системный вызов, напрямую через специфичный для системы механизм. Проблема в том, что это делает ваш код абсолютно непереносимым.
Итак, системный вызов - это:
В Linux, по крайней мере, механизм системного вызова работает в большинстве архитектур, помещая некоторые специально отформатированные данные (обычно своего рода структуру c) в некоторые регистры или заранее определенные адреса памяти.
Проблема, однако, заключается в том, что на самом деле ЦП вынужден переключиться в пространство ядра, чтобы он мог запустить привилегированный код ядра для обслуживания вызова. Это делается путем принудительного выполнения какой-либо ошибки (ошибка, являющаяся делением на 0, неопределенное переполнение или segfault и т. Д.), Что заставляет ядро взять на себя выполнение для обработки ошибки.
Обычно ядро обрабатывает сбои, либо завершая вызывающий процесс, либо запуская обработчик, предоставленный пользователем. Однако в случае системного вызова он вместо этого проверит предопределенные регистры и ячейки памяти, и если они содержат запрос системного вызова, он запустит его, используя данные, предоставленные пользовательским процессом в структуре в памяти. Обычно это нужно делать с помощью какой-то специально созданной вручную сборки, и для облегчения использования системного вызова для пользователя системная библиотека C должна обернуть его как функцию. Для интерфейса более низкого уровня см. http://man7.org/linux/man-pages/man2/syscall.2.html для получения некоторой информации о том, как работают системные вызовы и как вы можете затем звонить без C обертка.
Это чрезмерное упрощение, это верно не для всех архитектур (mips имеет специальную инструкцию syscall) и не обязательно работает одинаково во всех операционных системах. Тем не менее, если у вас есть какие-либо комментарии или вопросы, пожалуйста, задавайте их.
Изменено: Обратите внимание, что касается вашего комментария о вещах в / dev /, на самом деле это интерфейс ядра более высокого уровня, а не более низкий. Эти устройства фактически используют (около) 4 системных вызова ниже. Запись в них аналогична системному вызову записи, чтение системного вызова чтения, открытие / закрытие их эквивалентно системным вызовам открытия и закрытия и запуск ioctl вызывает специальный системный вызов ioctl, который сам по себе является интерфейсом для доступа к одному из многих системных вызовов ioctl. вызовы (специальные, обычно специфичные для устройства вызовы со слишком узким использованием, чтобы написать для них целый системный вызов).
Каждый системный вызов имеет связанное с ним целое число. Это целое число является функцией возврата значения системного вызова, количества аргументов для системного вызова и типа аргументов. Номер системного вызова является ничем иным, как смещением в вектор глобального системного вызова, этот вектор, доступный только в привилегированном режиме, содержит указатель на соответствующие обработчики. При обращении к системному вызову будет сгенерировано программное прерывание (trap-прерывание), следовательно, будет запущен обработчик ловушек, определяющий, какой системный вызов должен быть вызван. Затем ядро копирует аргументы системного вызова, переданные пользователем, который находится в стеке, в регистры процессора, и после завершения запрашиваемой услуги данные копируются обратно в стек из регистров процессора. Это одна из причин, по которой аргументы системных вызовов ограничены, так как аргументы будут скопированы в процессорные регистры, а процессоры имеют ограниченные регистры.
Системный вызов - это способ попросить вашу операционную систему (ядро) выполнить некоторую операцию от имени вашей программы, чтобы программа не может делать сама (или просто неудобна). Причина невозможности выполнения некоторых операций обычно заключается в том, что разрешение на их выполнение произвольной программе может поставить под угрозу целостность системы, например выполнение операций ввода-вывода (непосредственно в ОЗУ, перезапись чего-либо).
POSIX определяет интерфейс для программ, определенные функции, которые ваша программа может вызывать. Некоторые из них более или менее напрямую преобразуются в системные вызовы, другие требуют доработки. Это среда выполнения для вашего языка, например библиотека C, которая отвечает за предложение интерфейса POSIX, а также за упаковку аргументов и получение результатов обратно в руки вызывающей стороне.
Системы Unixy предлагают интерфейсы POSIX более или менее напрямую в виде системных вызовов. Обычно существует способ напрямую вызывать системные вызовы, ищите syscall (2)
, чтобы узнать, как использовать эту возможность в Linux.
Конечно, давайте посмотрим, из скольких направлений мы можем взглянуть на этого слона? вещь.
Фактический системный вызов в вашей собранной программе - это машинная инструкция, которая запускает повышение привилегий в режиме ядра, а в самом ядре - это код, который вызывает инструкция. Код libc (и среда исполнения каждого языка) устанавливает машинные регистры и параметры в памяти там, где код ядра ожидает их найти, которые могут быть явно странными из-за ограничений на эту машинную инструкцию.
Попав в код самой ОС, происходит немного зеркального разворачивания машинно-зависимых вещей, которые выполняла среда выполнения, а затем совершенно обычный вызов подпрограммы.
Если вы хотите точно увидеть, как это работает в полнофункциональной ОС, загрузите исходный код ядра ( git clone https://git.kernel.org/cgit/linux/kernel/ git / torvalds / linux.git /
) и сделайте, например, git grep -i system \ call
. Вытащите исходный код glibc и сделайте то же самое.