XNU内核案例(二)第一个用户进程Launchd

Launchd进程简介
  1. 苹果Mac OS X系统上,第一个进程是kernel_task ------ 内核进程(这个完全不同于Linux系统),PID为0;第二个进程是launchd(相当于linux的init进程),PID为1。
  2. 可以把kernel_task当作第0个进程,launchd当作第1个进程。
 
 
Launchd进程详细笔记(有时间我会把下面的翻译成中文,以便于大家)
There are four ways to launch daemons using launchd:
  • The preferred method is on-demand launching,
  • but launchd can launch daemons that run continuously,
  • and can replace inetd for launching inetd-style daemons.
  • In addition, launchd can start jobs at timed intervals.
 
Although launchd supports non-launch-on-demand daemons, this use is not recommended. The launchd daemon was designed to remove the need for dependency ordering among daemons. If you do not make your daemon be launched on demand, you will have to handle these dependencies in another way, such as by using the legacy startup item mechanism.
 
 
Launchd的好处
With the introduction of launchd in OS X v10.4, an effort was made to improve the steps needed to launch and maintain daemons. What launchd provides is a harness for launching your daemon as needed. To client programs, the port representing your daemon’s service is always available and ready to handle requests. In reality, the daemon may or may not be running. When a client sends a request to the port, launchd may have to launch the daemon so that it can handle the request. Once launched, the daemon can continue running or shut itself down to free up the memory and resources it holds. If a daemon shuts itself down, launchd once again relaunches it as needed to process requests.

In addition to the launch-on-demand feature, launchd provides the following benefits to daemon developers:

  • Simplifies the process of making a daemon by handling many of the standard housekeeping chores normally associated with launching a daemon.

  • Provides system administrators with a central place to manage daemons on the system.

  • Supports inetd-style daemons.

  • Eliminates the primary reason for running daemons as root. Because launchd runs as root, it can create low-numbered TCP/IP listen sockets and hand them off to the daemon.

  • Simplifies error handling and dependency management for inter-daemon communication. Because daemons launch on demand, communication requests do not fail if the daemon is not launched. They are simply delayed until the daemon can launch and process them.

 

Launchd的配置文件

The property list file is structured the same for both daemons and agents. You indicate whether it describes a daemon or agent by the directory you place it in. Property list files describing daemons are installed in/Library/LaunchDaemons, and those describing agents are installed in /Library/LaunchAgents or in the LaunchAgents subdirectory of an individual user’s Library directory. (The appropriate location for executables that you launch from your job is /usr/local/libexec.)
Required and recommended property list keys

Key

Description

Label

Contains a unique string that identifies your daemon to launchd. (required)

ProgramArguments

Contains the arguments used to launch your daemon. (required)

inetdCompatibility

Indicates that your daemon requires a separate instance per incoming connection. This causes launchd to behave like inetd, passing each daemon a single socket that is already connected to the incoming client. (required if your daemon was designed to be launched by inetd; otherwise, must not be included)

KeepAlive

This key specifies whether your daemon launches on-demand or must always be running. It is recommended that you design your daemon to be launched on-demand.

举个配置文件的例子(Apache服务的配置)
<plist version="1.0">
<dict>
<key>Disabled</key>
<true/>
<key>Label</key>
<string>org.apache.httpd</string>
<key>EnvironmentVariables</key>
<dict>
<key>XPC_SERVICES_UNAVAILABLE</key>
<string>1</string>
</dict>
<key>ProgramArguments</key>
<array>
<string>/usr/sbin/httpd</string>
<string>-D</string>
<string>FOREGROUND</string>
</array>
<key>OnDemand</key>
<false/>
</dict>
</plist>
当然配置文件可以添加其他keys
    <key>StandardOutPath</key> 
        <string>/var/log/myjob.log</string>
    <key>StandardErrorPath</key>
          <string>/var/log/myjob.log</string>
    <key>Debug</key>
          <true/
>
    <key>Keepalive</key> <true/>   <key>StartInterval</key>
           <integer>300</integer>
    <key>StartCalendarInterval</key>
           <dict>
                 <key>Minute</key>
                 <integer>45</integer>
                 <key>Hour</key>
                 <integer>13</integer>
                 <key>Day</key>
                 <integer>7</integer>
           </dict>
    <key>SoftResourceLimits</key>
           <dict>
                 <key>Core</key>
                 <integer>9223372036854775807</integer>
           </dict>
     <key>inetdCompatibility</key>
           <dict>
                 <key>Wait</key>
                 <false/>
           </dict>
 
比如上面增加daemon服务的标准输出的重定向、标准错误的重定向、debug开关、持续运行开关、间隔运行周期(每300s运行一次)、基于日历的执行计划、Coredump的条件、是否inetd兼容;
 
 
 
Daemon服务依赖注意
While launchd takes care of dependencies between daemons, in some cases, your daemon may depend on other system functionality that cannot be addressed in this manner. This section describes many of these special cases and how to handle them.
(1)Network Availability
If your daemon depends on the network being available, this cannot be handled with dependencies because network interfaces can come and go at any time in OS X. To solve this problem, you should use the network reachability functionality or the dynamic store functionality in the System Configuration framework. This is documented in System Configuration Programming Guidelines and System Configuration Framework Reference. For more information about network reachability, see “Determining Reachability and Getting Connected” in System Configuration Programming Guidelines.
(2)Disk or Server Availability
If your daemon depends on the availability of a mounted volume (whether local or remote), you can determine the status of that volume using the Disk Arbitration framework. This is documented in Disk Arbitration Framework Reference.
(3)Non-launchd Daemons
If your daemon has a dependency on a non-launchd daemon, you must take additional care to ensure that your daemon works correctly if that non-launchd daemon has not started when your daemon is started. The best way to do this is to include a loop at start time that checks to see if the non-launchd daemon is running, and if not, sleeps for several seconds before checking again.
Be sure to set up handlers for SIGTERM prior to this loop to ensure that you are able to properly shut down if the daemon you rely on never becomes available.
(4)User Logins
In general, a daemon should not care whether a user is logged in, and user agents should be used to provide per-user functionality. However, in some cases, this may be useful.
To determine what user is logged in at the console, you can use the System Configuration framework, as described in Technical Q&A QA1133.
(5)Kernel Extensions
If your daemon requires that a certain kernel extension be loaded prior to executing, you have two options: load it yourself, or wait for it to be loaded.
The daemon may manually request that an extension be loaded. To do this, run kextload with the appropriate arguments using exec or variants thereof. I/O Kit kernel extensions should not be loaded with kextload; the I/O Kit will load them automatically when they are needed.

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。