2015-04-21 7 views
0

В течение многих лет у нас был сценарий мониторинга процесса/контроля как часть нашего приложения. Поведение скрипта по умолчанию заключается в демоннировании самого себя. Часто скрипт запускается, по необходимости, не-привилегированными пользователями. По причинам, которые я не буду излагать, нам нужно сохранить сценарий и такое поведение.Как демонировать незащищенный скрипт в OSX Yosemite 10.10.3+

На OSX систем, мы традиционно был сценарий перезагрузки себя в фоновом режиме через запуска сценария /USR/libexec/StartupItemContext, представленной Apple. Это ставит наш процесс в контексте загрузки bootstrap, а не в контексте начальной загрузки. Это необходимо, потому что без этого контекстного переключателя, если и когда пользователь выходит из системы, что также часто необходимо, скрипт теряет доступ к службам каталогов, getpwuid(), службам DNS и т. Д. Исходные внутренние строки, которые демонизировали сценарий, выглядели по существу как это (в Perl):

my $cmd = "/usr/libexec/StartupItemContext myscript @Commandline > logs/startup 2>&1" ;   
system("$cmd &") ; 
exit 0 ; 

Когда OSX Yosemite вышел, что StartupItemContext скрипт исчез, поэтому мы перешли на прямой вызов из launchctl:

my $cmd = "/usr/launchctl bsexec/myscript @Commandline > logs/startup 2>&1" ;   
system("$cmd &") ; 
exit 0 ; 

С недавней OSX 10.10.3 обновления, однако, bsexec субкоманду launchctl вдруг требует привилегий суперпользователя:

% launchctl bsexec 
This subcommand requires root privileges: bsexec 
% 

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

Кажется, что Glassfish has encountered this problem и обратился к нему с a patch, который заменяет

/bin/launchctl bsexec/

с

nohup 

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

Что новое, канонический способ демона процесса на OSX начиная от непривилегированного, Маха «вход» самозагрузка контекста, без потери доступа к критически важным системным службам, как DNS и т.д., когда пользователь выходит из системы?

ответ

3

«из непривилегированного,« загрузочного контекста »« Маха »« к сожалению, вряд ли будет иметь «канонический путь». Единственный канонический способ - запустить сервисы по запросу через launchd. Даже «bsexec» едва поддерживается и едва документирован. По моему опыту, невозможно идти в ногу с изменениями OS X и никогда не перепроектировать ваши системы запуска. Я редизайн системы демона о каждом другом выпуске, потому что Apple нарушает его, и они будут продолжать ломать его. Единственный ответ - попытаться упростить свои требования. Но практически любой процесс, который хочет работать все время, а не по требованию, прямо противоречит заявленным намерениям Apple, поэтому он будет стремиться к разрыву.

Решение, данное Apple, заключается в создании LaunchDaemon и присвоении ему UserName в вашем стартовом plist. Вы должны начать пользоваться привилегиями, а затем переключиться на пользователя (и он должен быть фиксированным пользователем, а не «зарегистрированным пользователем», поскольку это будет LaunchAgent). Вы не можете обновить свой доступ таким образом. Вы не должны демонизировать себя (опять же, канонический ответ: не делайте этого. См. Страницу руководства launchd.plist.)

Я подозреваю, что решение Glassfish nohup - это просто уловка, которая фактически не помещает их в Маховский контекст. Они просто пытаются избежать убийства, когда выйдет родительская оболочка. Это, вероятно, вам не поможет.

По моему опыту, самые надежные решения являются многочастными. Вы завершаете одну часть, которая запускается как система LaunchDaemon (с KeepAlive), и еще одна часть, которая является пользователем LaunchAgent, и вы разрешаете им общаться через IPC, чтобы вы могли получить доступ к контексту, который вам нужен для каждого действия, которое вам нужно выполнить , Да, это, как правило, намного сложнее реализовать. Более простые решения, как правило, не работают.

И, конечно, вы должны постоянно спрашивать себя «есть любой способ я мог бы достичь этого, делая то, что хочет от меня». Это означает, что XPC настоятельно рекомендуется, за которым следуют LaunchDaemons и LaunchAgents по требованию. Если вы создадите свою систему для использования компонентов XPC, вы, скорее всего, выберете больше обновлений OS X. Любая работа вокруг вас, которая не использует эти штуки, вероятно, придется исправлять снова в 10.11.

+0

Большое спасибо @Rob за информированный эскиз о том, как перестроить это. Чтобы создать свободу действий для этого, знаете ли вы какую-либо краткосрочную уловку для нашего предстоящего (недельного) срока выпуска, кроме требований, нарушающих требования _sudo_? Например, [старые технические примечания] (https://developer.apple.com/library/mac/technotes/tn2083/_index.html) предполагают, что в дополнение к контексту «входа» есть «пользовательский» сценарий начальной загрузки. Есть ли способ запустить процесс, чтобы он попадал в «пользователь» вместо контекста «входа в систему», поэтому, надеюсь, сохранился выход из системы? Мы получили ослепленные изменения Apple здесь, спасибо – lcikgl

+1

Что TN - это карта, которую вы хотите. Я возвращаюсь к нему все время. Я верю, что вы смотрите на не-GUI LaunchAgent. Я не думаю, что они выживут. Все, что угодно «для пользователя» будет хотеть прекратить, когда пользователь уйдет. Конечно, вы можете попробовать, поставив plist в/Library/LaunchAgents. Вы можете попытаться разблокировать и отделить от своего родителя (может потребоваться двойная вилка). Возможно, это может защитить вас от выхода из системы. –