Home > Articles

This chapter is from the book

The init Phase

Objective: The init phase has undergone major changes in Solaris 10. Even if you are experienced on previous versions of Solaris OE, this section introduces the svc.startd daemon and the Service Management Facility (SMF), which are new in Solaris 10 and will be tested heavily on the exam.

After control of the system is passed to the kernel, the system begins the last stage of the boot process—the init stage. In this phase of the boot process, the init daemon (/sbin/init) reads the /etc/default/init file to set any environment variables for the shell that init invokes. By default, the CMASK and variables are set. These values get passed to any processes that init starts. Then, init reads the /etc/inittab file and executes any process entries that have sysinit in the action field so that any special initializations can take place before users log in.

After reading the /etc/inittab file, init starts the svc.startd daemon, which is responsible for starting and stopping other system services such as mounting file systems and configuring network devices. In addition, svc.startd will execute legacy run control (rc) scripts, which are described later in this section.

The /sbin/init command sets up the system based on the directions in /etc/inittab. Each entry in the /etc/inittab file has the following fields:


Table 3.23 provides a description of each field.

Table 3.23 Fields in the inittab File




A unique identifier


The run level(s)


How the process is to be run


The name of the command to execute

Valid action keywords are listed in Table 3.24:

Table 3.24 inittab action Field Values




Executes the process before init tries to access the console via the console prompt. init waits for the completion of the process before it continues to read the inittab file.


Indicates that the system has received a powerfail signal.

The following example shows a default /etc/inittab file:

ap::sysinit:/sbin/autopush -f /etc/iu.ap
sp::sysinit:/sbin/soconfig -f /etc/sock2path
smf::sysinit:/lib/svc/bin/svc.startd >/dev/msglog 2<>/dev/msglog </dev/console
p3:s1234:powerfail:/usr/sbin/shutdown -y -i5 -g0 >/dev/msglog 2<>/dev/msglog

The init process performs the following tasks based on the entries found in the default /etc/inittab file:

    Line 1: Initializes the STREAMS modules used for communication services.

    Line 2: Configures the socket transport providers for network connections.

    Line 3: Initializes the svc.startd daemon for SMF.

    Line 4: Describes the action to take when the init daemon receives a power fail shutdown signal.

The Solaris Management Facility (SMF) Service

Objective: Explain the Service Management Facility and the phases of the boot process.

  • Use Service Management Facility or legacy commands and scripts to control both the boot and shutdown procedures.

In Solaris 10, the svc.startd daemon replaces the init process as the master process starter and restarter. Where in previous versions of Solaris, init would start all processes and bring the system to the appropriate "run level" or "init state." Now SMF, or more specifically, the svc.startd daemon, assumes the role of starting system services.

The advantages of using SMF to manage system services over the traditional Unix startup scripts that, in the past, were run by the init process are

  • SMF automatically restarts failed services in the correct order, whether they failed as the result of administrator error, software bug, or were affected by an uncorrectable hardware error. The restart order is defined by dependency statements within the SMF facility.
  • The system administrator can view and manage services as well as view the relationships between services and processes.
  • Allows the system administrator to back up, restore, and undo changes to services by taking automatic snapshots of service configurations.
  • Allows the system administrator to interrogate services and determine why a service may not be running.
  • Allows services to be enabled and disabled either temporarily or permanently.
  • Allows the system administrator to delegate tasks to non-root users, giving these users the ability to modify, enable, disable, or restart system services.
  • Large systems boot and shutdown faster because services are started and stopped in parallel according to dependencies setup in the SMF.
  • Allows customization of output sent to the boot console to be either be as quiet as possible, which is the default, or to be verbose by using boot -m verbose from the OpenBoot prompt.
  • Provides compatibility with legacy RC scripts.

Those of you who have experience on previous versions of Solaris will notice a few differences immediately:

  • The boot process creates fewer messages. All of the information that was provided by the boot messages in previous versions of Solaris is located in the /var/svc/log directory. You still have the option of booting the system with the boot -v option, which provides more verbose boot messages.
  • Because SMF is able to start services in parallel, the boot time is substantially quicker than in previous versions of Solaris.
  • Since services are automatically restarted if possible, it may seem that a process refuses to die. The svcadm command should be used to disable any SMF service that should not be running.
  • Many of the scripts in /etc/init.d and /etc/rc*.d have been removed, as well as entries in the /etc/inittab file so that the services can be administered using SMF. You’ll still find a few RC scripts that still remain in the /etc/init.d directory such as sendmail, nfs.server, and dhcp, but most of these legacy RC scripts simply execute the svcadm command to start the services through the SMF. Scripts and inittab entries that may still exist from legacy applications or are locally developed will continue to run. The legacy services are started after the SMF services so that service dependencies do not become a problem.

The service instance is the fundamental unit of administration in the SMF framework, and each SMF service has the potential to have multiple versions of it configured. A service instance is either enabled or disabled with the svcadm command described later in this chapter. An instance is a specific configuration of a service, and multiple instances of the same service can run in the same Solaris instance. For example, a web server is a service. A specific web server daemon that is configured to listen on port 80 is an instance. Another instance of the web server service could have different configuration requirements listening on port 8080. The service has system-wide configuration requirements, but each instance can override specific requirements, as needed.

Services are represented in the SMF framework as service instance objects, which are children of service objects. These instance objects can inherit or override the configuration settings of the parent service object. Multiple instances of a single service are managed as child objects of the service object.

Services are not just the representation for standard long-running system services such as httpd or nfsd. Services also represent varied system entities that include third-party applications such as Oracle software. In addition, a service can include less traditional entities such as the following:

  • A physical network device
  • A configured IP address
  • Kernel configuration information

The services started by svc.startd are referred to as milestones. The milestone concept replaces the traditional run levels that were used in previous versions of Solaris. A milestone is a special type of service that represents a group of services. A milestone is made up of several SMF services. For example, the services that instituted run levels S, 2, and 3 in previous version of Solaris are now represented by milestone services named:

  • milestone/single-user (equivalent to run level S)
  • milestone/multi-user (equivalent to run level 2)
  • milestone/multi-user-server(equivalent to run level 3)

Other milestones that are available in the Solaris 10 OE are

  • milestone/name-services
  • milestone/devices
  • milestone/network
  • milestone/sysconfig

An SMF manifest is an XML (Extensible Markup Language) file that contains a complete set of properties that are associated with a service or a service instance. The properties are stored in files and subdirectories located in /var/svc/manifest. Manifests should not be edited directly to modify the properties of a service. The service configuration repository is the authoritative source of the service configuration information, and the service configuration repository can only be manipulated or queried using SMF interfaces, which are command-line utilities described later in this section.

Each service instance is named with a Fault Management Resource Identifier or FMRI. The FMRI includes the service name and the instance name. For example, the FMRI for the ftp service is svc:/network/ftp:default, where network/ftp identifies the service and default identifies the service instance.

You may see various forms of the FMRI that all refer to the same service instance, as follows:


An FMRI for a legacy service will have the following format:


where the lrc (legacy run control) prefix indicates that the service is not managed by SMF. The pathname /etc/rc3_d refers to the directory where the legacy script is located, and S90samba is the name of the run control script. See the section titled "Using the Run Control Scripts to Stop or Start Services" later in this chapter for information on run control scripts.

The service names will include a general functional category which include the following:

  • Application
  • Device
  • Milestone
  • Network
  • Platform
  • Site
  • System

Service Dependencies

In earlier versions of Solaris, processes were started at bootup by their respective shell scripts, which ran in a pre-determined sequence. Sometimes, one of these shell scripts failed for various reasons. Perhaps it was an error in the script or one of the daemons did not start for various reasons. When a script failed, the other scripts were started regardless, and sometimes these scripts failed because a previous process failed to start. Tracking the problem down was difficult for the system administrator.

To remedy the problem with sequencing scripts, Sun uses the SMF to manage the starting and stopping of services. The SMF understands the dependencies that some services have on other services. With SMF, if a service managed by the SMF fails or is terminated, all dependent processes will be taken offline until the required process is restarted. The interdependency is started by means of a service contract, which is maintained by the kernel and is where the process interdependency, the restarter process, and the startup methods are all described.

Most service instances have dependencies on other services or files. Those dependencies control when the service is started and automatically stopped. When the dependencies of an enabled service are not satisfied, the service is kept in the offline state. When the service instance dependencies are satisfied, the service is started or restarted by the svc.startd daemon. If the start is successful, the service is transitioned to the online state. There are four types of service instance dependencies listed below.

  • require_all The dependency is satisfied when all cited services are running (online or degraded), or when all indicated files are present.
  • require_any—The dependency is satisfied when one of the cited services is running (online or degraded), or when at least one of the indicated files is present.
  • optional_all—The dependency is satisfied when all of the cited services are running (online or degraded), disabled, in the maintenance state, or when cited services are not present. For files, this type is the same as require_all.
  • exclude_all—The dependency is satisfied when all of the cited services are disabled, in the maintenance state, or when cited services or files are not present.

Each service or service instance must define a set of methods that start, stop, and optionally refresh the service. These methods can be listed and modified for each service using the svccfg command described later in this chapter.

A service instance is satisfied and started when its criteria, for the type of dependency, are met. Dependencies are satisfied when cited services move to the online state. Once running (online or degraded), if a service instance with a require_all, require_any, or optional_all dependency is stopped or refreshed, the SMF considers why the service was stopped and uses the restart_on attribute of the dependency to decide whether to stop the service. restart_on attributes are defined in Table 3.25x

Table 3.25 restart_on Values






stop due to error





non-error stop










A service is considered to have stopped due to an error if the service has encountered a hardware error or a software error such as a core dump. For exclude_all dependencies, the service is stopped if the cited service is started and the restart_on attribute is not none.

You can use the svcs command, described later in this chapter, to view service instance dependencies and to troubleshoot failures. You’ll also see how to use the svccfg command to modify service dependencies.

SMF Command-line Administration Utilities

The SMF provides a set of command-line utilities used to administer and configure the SMF. Table 3.26 describes these utilities.

Table 3.26 SMF Command-line Utilities




Used to configure and view services controlled by the inetd daemon. Described in more detail in Chapter 8, "The Solaris Network Environment."


Used to perform common service management tasks such as enabling, disabling, or restarting service instances.


Used to display and manipulate the contents of the service configuration repository.


Used to retrieve property values from the service configuration repository with output that is appropriate for use in shell scripts.


Used to obtain a detailed view of the service state of all service instances in the configuration repository.

To report the status of all enabled service instances and get a list of the various services that are running, use the svcs command with no options as follows:

svcs | more

The svcs command obtains information about all service instances from the service configuration repository and displays the state, start time, and FMRI of each service instance as follows:

legacy_run  14:10:49 lrc:/etc/rc2_d/S10lu
legacy_run  14:10:49 lrc:/etc/rc2_d/S20sysetup
legacy_run  14:10:50 lrc:/etc/rc2_d/S40llc2
legacy_run  14:10:50 lrc:/etc/rc2_d/S42ncakmod
legacy_run  14:10:50 lrc:/etc/rc2_d/S47pppd
legacy_run  14:10:50 lrc:/etc/rc2_d/S70uucp
Output has been truncated . . . . 
online   	  14:09:37 svc:/system/svc/restarter:default
online   	  14:09:48 svc:/network/pfil:default
online   	  14:09:48 svc:/network/loopback:default
online   	  14:09:48 svc:/milestone/name-services:default
online   	  14:09:50 svc:/system/filesystem/root:default
online   	  14:09:54 svc:/system/filesystem/usr:default
online   	  14:09:56 svc:/system/device/local:default
online   	  14:09:57 svc:/milestone/devices:default
online   	  14:09:57 svc:/network/physical:default
online  	  14:09:58 svc:/milestone/network:default

The state of each service is one of the following:

  • degraded—The service instance is enabled, but is running at a limited capacity.
  • disabled—The service instance is not enabled and is not running.
  • legacy_run—The legacy service is not managed by SMF, but the service can be observed. This state is only used by legacy services that are started with RC scripts.
  • maintenance—The service instance has encountered an error that must be resolved by the administrator.
  • offline—The service instance is enabled, but the service is not yet running or available to run.
  • online—The service instance is enabled and has successfully started.
  • uninitialized—This state is the initial state for all services before their configuration has been read.

Running the svcs command without options will display the status of all enabled services. Use the -a option to list all services, including disabled services as follows:

svcs -a

The result is a listing of all services as follows:

. .. . <output has been truncated>
disabled  15:48:41 svc:/network/shell:kshell
disabled  15:48:41 svc:/network/talk:default
disabled  15:48:42 svc:/network/rpc/ocfserv:default
disabled  15:48:42 svc:/network/uucp:default
disabled  15:48:42 svc:/network/security/krb5_prop:default
disabled  15:48:42 svc:/network/apocd/udp:default
online   15:47:44 svc:/system/svc/restarter:default
online   15:47:47 svc:/network/pfil:default
online   15:47:48 svc:/network/loopback:default
online   15:47:50 svc:/system/filesystem/root:default
. .. . <output has been truncated>

To display information on selected services, you can supply the FMRI as an argument to the svcs command as follows:

svcs -l network

With the -l option, the system displays detailed information about the network service instance. The network FMRI specified in the previous example is a general functional category and is also called the network milestone. The information displayed by the previous command is as follows:

fmri   	  svc:/milestone/network:default
name    	  Network milestone
enabled  	  true
state  	  online
next_state  none
state_time  Wed Jul 27 14:09:58 2005
alt_logfile /etc/svc/volatile/milestone-network:default.log
restarter   svc:/system/svc/restarter:default
dependency  require_all/none svc:/network/loopback (online)
dependency  require_all/none svc:/network/physical (online)

Use the -d option to view which services are started at the network:default milestone, as follows:

svcs -d milestone/network:default 

The system displays

online   Jul_27 svc:/network/loopback:default
online   Jul_27 svc:/network/physical:default 

Another milestone is the multi-user milestone, which is displayed as follows:

svcs -d milestone/multi-user

The system displays all of the services started at the multi-user milestone:

online   Jul_27 svc:/milestone/name-services:default
online   Jul_27 svc:/milestone/single-user:default
online   Jul_27 svc:/system/filesystem/local:default
online   Jul_27 svc:/network/rpc/bind:default
online   Jul_27 svc:/milestone/sysconfig:default
online   Jul_27 svc:/network/inetd:default
online   Jul_27 svc:/system/utmp:default
online   Jul_27 svc:/network/nfs/client:default
online   Jul_27 svc:/system/system-log:default
online   Jul_27 svc:/network/smtp:sendmail 

Many of these services have their own dependencies, services that must be started before they get started. We refer to these as sub-dependencies. For example, one of the services listed is the svc:/network/inetd:default service. A listing of the sub-dependencies for this service can be obtained by typing

svcs -d network/inetd

The system displays the following dependencies:

disabled  15:47:57 svc:/network/inetd-upgrade:default
online    15:47:48 svc:/network/loopback:default
online    15:48:01 svc:/milestone/network:default
online    15:48:30 svc:/milestone/name-services:default
online    15:48:33 svc:/system/filesystem/local:default
online    15:48:34 svc:/network/rpc/bind:default
online    15:48:36 svc:/milestone/sysconfig:default

The -d option, in the previous example, lists the services or service instances upon which the multi-user service instance is dependent. These are the services that must be running before the multi-user milestone is reached. The -D option shows which other services depend on the milestone/multi-user service as follows:

svcs -D milestone/multi-user

The system displays the following output indicating that the dhcp-server and multi-user-server services are dependent on the multi-user service:

online   Jul_27 svc:/network/dhcp-server:default
online   Jul_27 svc:/milestone/multi-user-server:default

To view processes associated with a service instance, use the -p option as follows:

svcs -p svc:/network/inetd:default

The system displays processes associated with the svc:/network/inetd:default service. In this case, information about the inetd process is shown as follows:

online   Jul_27 svc:/network/inetd:default
    	   Jul_27  231 inetd

Viewing processes using svcs -p instead of the traditional ps command makes it easier to track all of the processes associated with a particular service.

If a service fails for some reason and cannot be restarted, you can list the service using the -x option as follows:

svcs -x

The system will display:

svc:/application/print/server:default (LP print server)
 State: disabled since Thu Sep 22 18:55:14 2005
Reason: Disabled by an administrator.
   See: http://sun.com/msg/SMF-8000-05
   See: lpsched(1M)
Impact: 2 dependent services are not running. (Use -v for list.)

The example shows that the LP print service has not started and provides an explanation that the service has not been enabled.

Starting and Stopping Services Using SMF

To disable services in previous versions of Solaris, the system administrator had to search out and rename the relevant RC script(s) or comment out statements in a configuration file such as modifying the inetd.conf file when disabling ftp.

SMF makes it much easier to locate services and their dependencies. To start a particular service using SMF, the service instance must be enabled using the svcadm enable command. By enabling a service, the status change is recorded in the service configuration repository. The enabled state will persist across reboots as long as the service dependencies are met. The following example demonstrates how to use the svcadm command to enable the ftp server:

svcadm enable network/ftp:default

To disable the ftp service, use the disable option as follows:

svcadm disable network/ftp:default

To verify the status of the service, type

svcs network/ftp

The system displays the following:

online   16:07:08 svc:/network/ftp:default

The svcadm command allows the following subcommands:

  • Enable—Enables the service instances.
  • Disable—Disables the service instances.
  • Restart—Requests that the service instances be restarted.
  • Refresh—For each service instance specified, refresh requests that the assigned restarter update the service's running configuration snapshot with the values from the current configuration. Some of these values take effect immediately (for example, dependency changes). Other values do not take effect until the next service restart.
  • Clear—For each service instance specified, if the instance is in the maintenance state, signal to the assigned restarter that the service has been repaired. If the instance is in the degraded state, request that the assigned restarter take the service to the online state.

The svcadm command can also be used to change milestones. In the following step by step, I'll use the svcadm command to determine my current system state (milestone) and then change the system default milestone to single-user.


3.2 Changing Milestones

  1. First, check to see what the default milestone is set to for your system by using the svcprop command. This command will retrieve the SMF service configuration properties for my system
  2. # svcprop restarter|grep milestone

    The system responds with the following, indicating that my system is set to boot to the multi-user milestone by default:

    options/milestone astring svc:/milestone/multi-user:default
  3. I'll check to see which milestone the system is currently running at:
  4. svcs | grep milestone

    The system responds with

    disabled  16:16:36 svc:/milestone/multi-user-server:default
    online    16:16:36 svc:/milestone/name-services:default
    online    16:16:43 svc:/milestone/devices:default
    online    16:16:45 svc:/milestone/network:default
    online    16:16:57 svc:/milestone/single-user:default
    online    16:17:03 svc:/milestone/sysconfig:default
    online    16:17:16 svc:/milestone/multi-user:default

    From the output, I see that multi-user-server is not running, but multi-user is running.

  5. To start the transition to the single-user milestone, type
  6. svcadm milestone single-user

    The system responds with the following, prompting for the root password and finally entering single-user mode:

    Root password for system maintenance (control-d to bypass): <enter root password>
    single-user privilege assigned to /dev/console.
    Entering System Maintenance Mode
    Sep 22 17:22:09 su: 'su root' succeeded for root on /dev/console
    Sun Microsystems Inc. SunOS 5.10  Generic January 2005
  7. Verify the current milestone with the following command:
  8. svcs -a | grep milestone

    The system responds with:

    disabled  16:16:36 svc:/milestone/multi-user-server:default
    disabled  17:21:37 svc:/milestone/multi-user:default
    disabled  17:21:37 svc:/milestone/sysconfig:default
    disabled  17:21:39 svc:/milestone/name-services:default
    online    16:16:43 svc:/milestone/devices:default
    online    16:16:45 svc:/milestone/network:default
    online    16:16:57 svc:/milestone/single-user:default

    The output indicates that the multi-user and multi-user-server milestones are disabled, and the single-user milestone is the only milestone that is currently online.

  9. Finally, I'll bring the system backup to the multi-user-server milestone:
  10. svcadm milestone milestone/multi-user-server:default

    Issuing the svcs command again shows that the multi-user-server milestone is back online:

    svcs -a |grep milestone
    online   16:16:43 svc:/milestone/devices:default
    online   16:16:45 svc:/milestone/network:default
    online   16:16:57 svc:/milestone/single-user:default
    online   17:37:06 svc:/milestone/name-services:default
    online   17:37:12 svc:/milestone/sysconfig:default
    online   17:37:23 svc:/milestone/multi-user:default
    online   17:37:31 svc:/milestone/multi-user-server:default

At bootup, svc.startd retrieves the information in the service configuration repository and starts services when their dependencies are met. The daemon is also responsible for restarting services that have failed and for shutting down services whose dependencies are no longer satisfied.

In the following example, users cannot telnet into the server, so I check on the telnet service using the svcs -x command as follows:

svcs -x telnet

The results show that the service is not running:

svc:/network/telnet:default (Telnet server)
 State: disabled since Fri Sep 23 10:06:46 2005
Reason: Temporarily disabled by an administrator.
 	 See: http://sun.com/msg/SMF-8000-1S
   See: in.telnetd(1M)
   See: telnetd(1M)
Impact: This service is not running.

I’ll enable the service using the svcadm command as follows:

svcadm enable svc:/network/telnet:default

After enabling the service, check the status using the svcs command as follows:

# svcs -x telnet

The system responds with:

svc:/network/telnet:default (Telnet server)
 State: online since Fri Sep 23 10:20:47 2005
   See: in.telnetd(1M)
   See: telnetd(1M)
Impact: None.

Also, if a service that has been running but stops, try restarting the service using the svcadm restart command as follows:

svcadm restart svc:/network/telnet:default

Starting Services During Boot

Under SMF, the boot process is much quieter than previous versions of Solaris. This was done to reduce the amount of uninformative "chatter" that might obscure any real problems that might occur during boot.

Some new boot options have been added to control the verbosity of boot. One that you may find particularly useful is -m verbose, which prints a line of information when each service attempts to start up. This is similar to previous versions of Solaris where the boot messages were more verbose.

You can also boot the system using one of the milestones as follows:

boot -m milestone=single-user

The system will boot into single-user mode where only the basic services are started as shown when the svcs command is used to display services.

disabled  17:10:27 svc:/system/filesystem/local:default
disabled  17:10:27 svc:/system/identity:domain
disabled  17:10:27 svc:/system/sysidtool:net
disabled  17:10:28 svc:/system/cryptosvc:default
disabled  17:10:28 svc:/network/initial:default
disabled  17:10:28 svc:/network/rpc/bind:default
disabled  17:10:28 svc:/system/sysidtool:system
disabled  17:10:28 svc:/milestone/sysconfig:default
Output has been truncated . . . . .

This method of booting is slightly different than using the boot -s command. When the system is explicitly booted to a milestone, exiting the console administrative shell will not transition the system to multi-user mode, as boot -s does. To move to multi-user mode after boot -m milestone=single-user, use the following command:

svcadm milestone milestone/multi-user-server:default

The milestones that can be specified at boot time are

  • none
  • single-user
  • multi-user
  • multi-user-server
  • all

If you boot a system using one of the milestones and you do not include the -s option, the system will stay in the milestone state that you booted the system in. The system will not go into multi-user state automatically when you press Ctrl+D. You can however, get into the multi-user state by using the following command and all services will be restored:

svcadm milestone all

To boot the system without any milestones, type

boot -m milestone=none

The boot command instructs the svc.startd daemon to temporarily disable all services except for the master restarter named svc:/system/svc/restarter:default and start sulogin on the console. The "none" milestone can be very useful in troubleshooting systems that have failures early in the boot process.

To bring the system back down to single-user mode from multi-user mode, type

svcadm milestone milestone/single-user

The -d option can be used with the previous example to cause svcadm to make the given milestone the default boot milestone, which persists across reboots. This would be the equivalent of setting the default run level in the /etc/inittab file on previous versions of Solaris.

Other options that can be used with svcadm include

  • -r—Enables each service instance and recursively enables its dependencies.
  • -s—Enables each service instance and then waits for each service instance to enter the online or degraded state. svcadm will return early if it determines that the service cannot reach these states without administrator intervention.
  • -t—Temporarily enables or disables each service instance. Temporary enable or disable only lasts until reboot.

SMF Message Logging

In addition to the system logging methods described earlier in this chapter, each service has a log file in the /var/svc/log directory (or the /etc/svc/volatile directory, for services started before the single-user milestone) indicating when and how the system was started, whether it started successfully, and any messages it may have printed during its initialization. If a severe problem occurs during boot, you will be able to log in on the console in maintenance mode, and you can use the svcs command to help diagnose the problem, even on problems which would have caused boot to hang. Finally, the new boot -m boot option allows the system administrator to configure the boot process to be more verbose, printing a simple message when each service starts.

Creating New Service Scripts

Objective: Use Service Management Facility or legacy commands and scripts to control both the boot and shutdown procedures.

As you customize your system, you’ll create custom scripts to start and stop processes or services on your system. The correct procedure for incorporating these scripts into the SMF is as follows:

  • Determine the process for starting and stopping your service.
  • Establish a name for the service and the category this service falls into.
  • Determine whether your service runs multiple instances.
  • Identify any dependency relationships between this service and any other services. Practically every service has a dependency so that the service does not startup too soon in the boot process.
  • If a script is required to start and stop the process, create the script and place it in a local directory such as /lib/svc/method.
  • Create a service manifest file for your service in the /var/svc/manifest/site directory. This XML file describes the service and any dependency relationships. Service manifests are incorporated into the repository either by using the svccfg command or at boot time. See the service_bundle(4) manual page for a description of the contents of the SMF manifests.
  • Incorporate the script into the SMF using the svccfg utility.

The following step by step describes the process of setting up and enabling an existing service instance.


3.3 Enable the NFS Server Service

In the following example, I'll configure SMF to share the NFS resources on an NFS server.

  1. Log in as root or use a role that includes the Service Management rights profile.
  2. The NFS server services are not running as displayed by the following svcs command:
  3. svcs -a| grep -i nfs

    The system displays the following information about the NFS services:

    disabled  15:47:56 svc:/network/nfs/cbd:default
    disabled  15:47:59 svc:/network/nfs/server:default
    online    15:48:36 svc:/network/nfs/mapid:default
    online    15:48:36 svc:/network/nfs/status:default
    online    15:48:37 svc:/network/nfs/nlockmgr:default
    online    15:48:44 svc:/network/nfs/client:default
    online    15:54:26 svc:/network/nfs/rquota:default

    Notice that svc:/network/nfs/server:default is disabled.

  4. Set up the required NFS configuration file on the server. To share a file system named /data, I need to configure the /etc/dfs/dfstab file as described in Chapter 9. I add the following line to the NFS server configuration file:
  5. share -F nfs -o rw /data
  6. Enable the NFS service as follows:
  7. svcadm enable svc:/network/nfs/server
  8. Verify that the NFS server service is running by typing:
  9. svcs -a | grep -i nfs

    The system displays the following information:

    disabled  15:47:56 svc:/network/nfs/cbd:default
    online    15:48:44 svc:/network/nfs/client:default
    online    11:22:26 svc:/network/nfs/status:default
    online    11:22:26 svc:/network/nfs/nlockmgr:default
    online    11:22:27 svc:/network/nfs/mapid:default
    online    11:22:28 svc:/network/nfs/server:default
    online    11:22:28 svc:/network/nfs/rquota:default

This next step by step describes how to create a new service and incorporate it into the SMF. Taking the time to convert your existing RC scripts to SMF allows them to take advantage of automated restart capabilities that could be caused by hardware failure, unexpected service failure, or administrative error. Participation in the service management facility also brings enhanced visibility with svcs (as well as future-planned GUI tools) and ease of management with svcadm and other Solaris management tools. The task requires the creation of a short XML file and making a few simple modifications to the service RC script. The following step by step will take you through the process.


3.4 Converting an RC Script to SMF

Before I start, I’ll take an existing legacy RC script and place it under SMF control as a service. This script is named /etc/init.d/legacy and has the following entries:

case "$1" in

  /usr/bin/pkill -x -u 0 legacyprog

  echo "Usage: $0 { start | stop } "
  exit 1

exit 0

I’ll move this script to /lib/svc/method/legacyservice.

The most complex part of this procedure is writing the SMF manifest in XML. Currently, these manifests need to be created with an editor, but in the future, expect a GUI-based tool to aid in the creation of the manifest file. The service_bundle(4) man page describes this XML-based file, but you need to be familiar with the XML programming language, and that is beyond the scope of this book. Here’s a copy of my manifest for the service we are going to implement; I named it /var/svc/manifest/site/legacyservice, and I’ll describe the contents of the file in this section.

<?xml version="1.0"?>
<!DOCTYPE service_bundle SYSTEM
ident "@(#)newservice.xml 1.2 04/09/13 SMI"
<service_bundle type=’manifest’ name=’OPTnew:legacyservice’>



  <service_fmri value=’svc:/system/filesystem/local’ />

  <service_fmri value=’svc:/milestone/multi-user’ />

  exec=’/lib/svc/method/legacyservice start’
  timeout_seconds=’30’ />

  exec=’/lib/svc/method/legacyservice stop’
  timeout_seconds=’30’ />

<property_group name=’startd’ type=’framework’>
<propval name=’duration’ type=’astring’ value=’transient’

<instance name=’default’ enabled=’true’ />

<stability value=’Unstable’ />

    <loctext xml:lang=’C’>
    New service

Now let's take a closer look at the XML-based manifest file and the steps I took to create it.

  1. My file starts out with a standard header. After the header, I specify the name of the service, the type of service, the package providing the service, and the service name as follows:
  2. <?xml version="1.0"?>
    <!DOCTYPE service_bundle SYSTEM
    ident "@(#)newservice.xml 1.2 04/09/13 SMI"
    <service_bundle type='manifest' name='OPTnew:legacyservice'>
  3. I specify the service category, type, name, and version. These categories aren't used by the system, but help the administrator in identifying the general use of the service. These categories types are
    • application—Higher level applications, such as apache

      milestone—Collections of other services, such as name-services

      platform—Platform-specific services, such as Dynamic Reconfiguration daemons

      system—Solaris system services, such as coreadm

      device—Device-specific services

      network—Network/Internet services, such as protocols

      site—Site specific descriptions

    The service name describes what is being provided, and includes both any category identifier and the actual service name, separated by '/'. Service names should identify the service being provided. In this example, the entry I'll make to my manifest file is as follows:

  4. Identify whether your service will have multiple instances. The instance name describes any specific features about the instance. Most services deliver a "default" instance. Some (such as Oracle) may want to create instances based on administrative configuration choices. This service will have a single instance, so I'll make the following entry in the manifest:
  5. <single_instance />
  6. Define any dependencies for this service. I added the following entry to the manifest:
  7. <dependency
      <service_fmri value='svc:/system/filesystem/local' />

    The first entry states that the legacyservice requires the filesystem/local service.

  8. We now need to identify dependents. If I want to make sure that my service is associated with the multi-user milestone and that the multi-user milestone requires this service, I add the following entry to the manifest:
  9. <dependent
       <service_fmri value='svc:/milestone/multi-user' />

    By having the ability to identify dependents, I'm able to deliver a service that is a dependency of another service (milestone/multi-user) which I don't deliver. I can specify this in my legacyservice manifest without modifying the milestone/multi-user manifest, which I don't own. It's an easy way to have a service run before a Solaris default service.

    If all the dependent services have not been converted to SMF, you'll need to convert those too, as there is no way to specify a dependent on a legacy script.

    To avoid conflicts, it is recommended that you preface the dependent name with the name of your service. For example, if you're delivering a service (legacyservice) that must start before syslog, use the following entry:

  10. Specify how the service will be started and stopped. SMF interacts with your service primarily by its methods. The stop and start methods must be provided for services managed by svc.startd, and can either directly invoke a service binary or a script which handles care of more complex setup. The refresh method is optional for svc.startd managed services. I'll use the following start and stop methods:
  11. <exec_method
      exec='/lib/svc/method/legacyservice start'
      timeout_seconds='30' />
      exec='/lib/svc/method/legacyservice stop'
      timeout_seconds='30' />

    Timeouts must be provided for all methods. The timeout should be defined to be the maximum amount of time in seconds that your method might take to run on a slow system or under heavy load. A method which exceeds its timeout will be killed. If the method could potentially take an unbounded amount of time, such as a large file system fsck, an infinite timeout may be specified as '0'.

  12. Identify the service model—will it be started by inetd or svc.startd? My service will be started by svc.startd. svc.startd provides three models of service, which are
    • Transient services—These are often configuration services, which require no long-running processes to provide service. Common transient services take care of boot-time cleanup or load configuration properties into the kernel. Transient services are also sometimes used to overcome difficulties in conforming to the method requirements for contract or wait services. This is not recommended and should be considered a stopgap measure.

      Wait services—These services run for the lifetime of the child process, and are restarted when that process exits.

      Contract services—These are the standard system daemons. They require processes which run forever once started to provide service. Death of all processes in a contract service is considered a service error, which will cause the service to restart.

    The default service model is contract, but may be modified. For this example, I'm going to start the service with svc.startd. As a transient service, it will be started once and not restarted by adding the following lines to the manifest:

    <property_group name='startd' type='framework'>
    <propval name='duration' type='astring' value='transient'
  13. The next step is to create the instance name for the service by making the following entry:
  14. <instance name='default' enabled='true' />
  15. Finally, create template information to describe the service providing concise detail about the service. I'll assign a common name in the C locale. The common name should
    • Be short (40 characters or less)

      Avoid capital letters aside from trademarks like Solaris

      Avoid punctuation

      Avoid the word service (but do distinguish between client and server)

    I make the following entry in the manifest to describe my service as "New service":

        <loctext xml:lang='C'>
        New service
  16. Once the manifest is complete, is a good idea to verify the syntax using the xmllint program as follows:
  17. xmllint --valid /var/svc/manifest/site/legacyservice

    The xmllint program will parse the XML file and identify any errors in the code before you try to import it into SMF. The scvcfg program also can validate your file as follows, but the output is not as verbose as the xmllint command:

    svccfg validate /var/svc/manifest/site/legacyservice
  18. Once you've validated the syntax of your XML file, the new service needs to be imported in SMF by issuing the svccfg command as follows:
  19. svccfg import /var/svc/manifest/site/legacyservice
  20. The service should now be visible using the svcs command as follows:
  21. # svcs legacyservice
    -    svc:/site/legacyservice:default
  22. You can also see which services the legacyservice depends on by using the svcs -d command as follows:
  23. svcs -d legacyservice
    online   Sep_20 svc:/system/filesystem/local:default
  24. As a final step, enable the service using the svcadm command as follows:
  25. svcadm -v enable legacyservice
    svc:/site/legacyservice:default enabled.
  26. At any time, I can view the properties of a service using the svccfg command as follows:
  27. svccfg -v -s legacyservice

    The system responds with the following prompt:


    Use the listprop subcommand at the svccfg prompt to list the service properties:

    svc:/site/legacyservice> listprop
    usr      					dependency
    usr/entities    			fmri  svc:/system/filesystem/local
    usr/grouping    			astring require_all
    usr/restart_on   			astring none
    usr/type     				astring service
    general     				framework
    general/entity_stability  astring Unstable
    general/single_instance   boolean true
    dependents    			framework
    dependents/newservice  	astring svc:/milestone/multi-user
    startd     				framework
    startd/duration   		astring transient
    start      				method
    start/exec    			astring "/lib/svc/method/legacyservice start"
    start/timeout_seconds  	count 30
    start/type    			astring method
    stop      				method
    stop/exec     			astring "/lib/svc/method/legacyservice stop"
    stop/timeout_seconds  	count 30
    stop/type     			astring method
    tm_common_name   			template
    tm_common_name/C   		ustring "New service"

Legacy Services

Objective: Use Service Management Facility or legacy commands and scripts to control both the boot and shutdown procedures.

Solaris 10 still supports legacy RC scripts referred to as legacy services, but you will notice that the /etc/inittab file used by the init daemon has been significantly reduced. In addition, RC scripts that were located in the /etc/init.d directory and linked to the /etc/rc#.d directory have also been reduced substantially. For many of the scripts that remain, simply run the svcadm command to start the appropriate service.

SMF-managed services no longer use RC scripts or /etc/inittab entries for startup and shutdown, so the scripts corresponding to those services have been removed. In future releases of Solaris, more services will be managed by SMF, and these directories will become less and less populated. RC scripts and /etc/inittab entries that manage third-party–provided or locally developed services will continue to be run at boot. These services may not run at exactly the same point in boot as they had before the advent of SMF, but they are guaranteed to not run any earlier—any services which they had implicitly depended on will still be available.

For those readers who are experienced on Solaris versions prior to Solaris 10, you are accustomed to starting and stopping services via rc scripts. For instance, to stop and start the sshd daemon, you would type:

/etc/init.d/sshd stop
/etc/init.d/sshd start

In SMF, the correct procedure to start sshd is to type

svcadm enable -t network/ssh:default

To temporarily stop sshd, you would type

svcadm disable -t network/ssh:default

Or simply type

svcadm restart network/ssh:default

to stop and restart the sshd daemon.

Prior to Solaris 10, to send a HUP signal to the ssh daemon, we would have typed

kill -HUP ´cat /var/run/sshd.pid´

In Solaris 10, the correct procedure is to type

svcadm refresh network/ssh:default

Using the Run Control Scripts to Stop or Start Services

Although it is recommended that you use SMF to start and stop services as described in the previous section, "Creating New Service Scripts," functionality still exists to allow the use of run control scripts to start and stop system services at various run levels. Run control scripts were used in previous versions of Solaris to start and stop system services before SMF was introduced.

A run level is a system state (run state), represented by a number or letter that identifies the services and resources that are currently available to users. The who -r command can still be used to identify a systems run state as follows:

who -r

The system responds with the following indicating that run-level 3 is the current run state:

.  run-level 3 Aug 4 09:38  3  1 1

Since the introduction of SMF in Solaris 10, we now refer to these run states as milestones, and Table 3.26 describes how the legacy run states coincide with the Solaris 10 milestones.

Table 3.26 The System Run States

Run State (milestone)



Stops system services and daemons. Terminates all running processes. Unmounts all file systems.

S, s (single-user)

Single-user (system administrator) state. Only root is allowed to log in at the console, and any logged-in users are logged out when you enter this run level. Only critical file systems are mounted and accessible. All services except the most basic operating system services are shut down in an orderly manner.


Single-user (system administrator) state. If the system is booted into this run level, all local file systems are mounted. All services except the most basic operating system services are shut down.

2 (multi-user)

Normal multiuser operation, without network file systems (NFSs) shared: directories; locks interfaces and starts processes; starts the con daemon; cleans up the uucp tmp files; starts the lp system; and starts the sendmail daemon and syslog.

3 (multi-user-server)

Normal multi-use operation of a file server, with NFSs shared. Completes all the tasks in run state 2 and starts the NFS daemons.


Alternative multi-user state (currently not used).


Power-down state. Shuts down the system so that it is safe to turn off power to the system. If possible, automatically turns off system power on systems that support this feature.


Reboot state.

To support legacy applications that still use them, run control scripts have been carried over from Solaris 9. With run control scripts, each init state (milestone) has a corresponding series of run control scripts—which are referred to as rc scripts and are located in the /sbin directory—to control each run state. These rc scripts are as follows:

  • rc0
  • rc1
  • rc2
  • rc3
  • rc5
  • rc6
  • rcS

You can still use the init command to transition to between the various run states. The init daemon will simply pass the required run state to the svc.startd daemon for execution.

The SMF will execute the /sbin/rc<n> scripts, which in turn execute a series of other scripts that are located in the /etc directory. For each rc script in the /sbin directory, a corresponding directory named /etc/rc<n>.d contains scripts to perform various actions for that run state. For example, /etc/rc3.d contains files that are used to start and stop processes for run state 3.

The /etc/rc<n>.d scripts are always run in ASCII sort order shown by the ls command and have names of this form:


A file that begins with K is referred to as a stop script and is run to terminate (kill) a system process. A file that begins with S is referred to as a start script and is run to start a system process. Each of these start and stop scripts is called by the appropriate /sbin/rc# script. For example, the /sbin/rc0 script runs the scripts located in the /etc/rc0.d directory. The /sbin/rc# script will pass the argument start or stop to each script, based on their prefix and whether the name ends in .sh. There are no arguments passed to scripts that end in .sh.

All run control scripts are also located in the /etc/init.d directory, and all scripts must be /sbin/sh scripts. These files are hard linked to corresponding run control scripts in the /etc/rc<n>.d directories.

These run control scripts can also be run individually to start and stop services. For example, you can turn off NFS server functionality by typing /etc/init.d/nfs.server stop and pressing Enter. After you have changed the system configuration, you can restart the NFS services by typing /etc/init.d/nfs.server start and pressing Enter. If you notice, however, many of these RC scripts simply have svcadm commands embedded in them to perform the task of stopping and starting the service.

In addition to the svcs -p command, you can still use the pgrep command to verify whether a service has been stopped or started:

pgrep -f <service>

The pgrep utility examines the active processes on the system and reports the process IDs of the processes. See Chapter 5, "Managing System Processes," for details on this command.

Adding Scripts to the Run Control Directories

If you add a script to the run control directories, you put the script in the /etc/init.d directory and create a hard link to the appropriate rc<n>.d directory. You need to assign appropriate numbers and names to the new scripts so that they will be run in the proper ASCII sequence, as described in the previous section.

To add a new run control script to a system, follow the process in Step by Step 3.5.


3.5 Adding a Run Control Script

  1. Become the superuser.
  2. Add the script to the /etc/init.d directory:
  3. # cp <filename> /etc/init.d
    # cd /etc/init.d
    # chmod 744 <filename>
    # chown root:sys <filename>
  4. Create links to the appropriate rc<n>.d directory:
  5. # ln <filename> /etc/rc2.d/S<nnfilename>
    # ln <filename> /etc/rc<n>.d/K<nnfilename>
  6. Use the ls command to verify that the script has links in the specified directories:
  7. # ls -li /etc/init.d/<filename> /etc/rc?.d/[SK]*<filename>

The following example creates an rc script named program that starts up at run level 2 and stops at run level 0. Note the use of hard links versus soft links:

# cp program /etc/init.d
# cd /etc/init.d
# chmod 744 program
# chown root:sys program
# ln /etc/init.d/program /etc/rc2.d/S99program
 # ln /etc/init.d/program /etc/rc0.d/K01program

You can verify the links by typing this:

# ls -li /etc/init.d/program /etc/rc?.d/[SK]*program

The system displays the following:

389928 -rwxr--r-- 3 root  sys   69 Oct 26 23:31 /etc/init.d/program
389928 -rwxr--r-- 3 root  sys   69 Oct 26 23:31 /etc/rc0.d/K01program
389928 -rwxr--r-- 3 root  sys   69 Oct 26 23:31 /etc/rc2.d/S99program

InformIT Promotional Mailings & Special Offers

I would like to receive exclusive offers and hear about products from InformIT and its family of brands. I can unsubscribe at any time.


Pearson Education, Inc., 221 River Street, Hoboken, New Jersey 07030, (Pearson) presents this site to provide information about products and services that can be purchased through this site.

This privacy notice provides an overview of our commitment to privacy and describes how we collect, protect, use and share personal information collected through this site. Please note that other Pearson websites and online products and services have their own separate privacy policies.

Collection and Use of Information

To conduct business and deliver products and services, Pearson collects and uses personal information in several ways in connection with this site, including:

Questions and Inquiries

For inquiries and questions, we collect the inquiry or question, together with name, contact details (email address, phone number and mailing address) and any other additional information voluntarily submitted to us through a Contact Us form or an email. We use this information to address the inquiry and respond to the question.

Online Store

For orders and purchases placed through our online store on this site, we collect order details, name, institution name and address (if applicable), email address, phone number, shipping and billing addresses, credit/debit card information, shipping options and any instructions. We use this information to complete transactions, fulfill orders, communicate with individuals placing orders or visiting the online store, and for related purposes.


Pearson may offer opportunities to provide feedback or participate in surveys, including surveys evaluating Pearson products, services or sites. Participation is voluntary. Pearson collects information requested in the survey questions and uses the information to evaluate, support, maintain and improve products, services or sites, develop new products and services, conduct educational research and for other purposes specified in the survey.

Contests and Drawings

Occasionally, we may sponsor a contest or drawing. Participation is optional. Pearson collects name, contact information and other information specified on the entry form for the contest or drawing to conduct the contest or drawing. Pearson may collect additional personal information from the winners of a contest or drawing in order to award the prize and for tax reporting purposes, as required by law.


If you have elected to receive email newsletters or promotional mailings and special offers but want to unsubscribe, simply email information@informit.com.

Service Announcements

On rare occasions it is necessary to send out a strictly service related announcement. For instance, if our service is temporarily suspended for maintenance we might send users an email. Generally, users may not opt-out of these communications, though they can deactivate their account information. However, these communications are not promotional in nature.

Customer Service

We communicate with users on a regular basis to provide requested services and in regard to issues relating to their account we reply via email or phone in accordance with the users' wishes when a user submits their information through our Contact Us form.

Other Collection and Use of Information

Application and System Logs

Pearson automatically collects log data to help ensure the delivery, availability and security of this site. Log data may include technical information about how a user or visitor connected to this site, such as browser type, type of computer/device, operating system, internet service provider and IP address. We use this information for support purposes and to monitor the health of the site, identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents and appropriately scale computing resources.

Web Analytics

Pearson may use third party web trend analytical services, including Google Analytics, to collect visitor information, such as IP addresses, browser types, referring pages, pages visited and time spent on a particular site. While these analytical services collect and report information on an anonymous basis, they may use cookies to gather web trend information. The information gathered may enable Pearson (but not the third party web trend services) to link information with application and system log data. Pearson uses this information for system administration and to identify problems, improve service, detect unauthorized access and fraudulent activity, prevent and respond to security incidents, appropriately scale computing resources and otherwise support and deliver this site and its services.

Cookies and Related Technologies

This site uses cookies and similar technologies to personalize content, measure traffic patterns, control security, track use and access of information on this site, and provide interest-based messages and advertising. Users can manage and block the use of cookies through their browser. Disabling or blocking certain cookies may limit the functionality of this site.

Do Not Track

This site currently does not respond to Do Not Track signals.


Pearson uses appropriate physical, administrative and technical security measures to protect personal information from unauthorized access, use and disclosure.


This site is not directed to children under the age of 13.


Pearson may send or direct marketing communications to users, provided that

  • Pearson will not use personal information collected or processed as a K-12 school service provider for the purpose of directed or targeted advertising.
  • Such marketing is consistent with applicable law and Pearson's legal obligations.
  • Pearson will not knowingly direct or send marketing communications to an individual who has expressed a preference not to receive marketing.
  • Where required by applicable law, express or implied consent to marketing exists and has not been withdrawn.

Pearson may provide personal information to a third party service provider on a restricted basis to provide marketing solely on behalf of Pearson or an affiliate or customer for whom Pearson is a service provider. Marketing preferences may be changed at any time.

Correcting/Updating Personal Information

If a user's personally identifiable information changes (such as your postal address or email address), we provide a way to correct or update that user's personal data provided to us. This can be done on the Account page. If a user no longer desires our service and desires to delete his or her account, please contact us at customer-service@informit.com and we will process the deletion of a user's account.


Users can always make an informed choice as to whether they should proceed with certain services offered by InformIT. If you choose to remove yourself from our mailing list(s) simply visit the following page and uncheck any communication you no longer want to receive: www.informit.com/u.aspx.

Sale of Personal Information

Pearson does not rent or sell personal information in exchange for any payment of money.

While Pearson does not sell personal information, as defined in Nevada law, Nevada residents may email a request for no sale of their personal information to NevadaDesignatedRequest@pearson.com.

Supplemental Privacy Statement for California Residents

California residents should read our Supplemental privacy statement for California residents in conjunction with this Privacy Notice. The Supplemental privacy statement for California residents explains Pearson's commitment to comply with California law and applies to personal information of California residents collected in connection with this site and the Services.

Sharing and Disclosure

Pearson may disclose personal information, as follows:

  • As required by law.
  • With the consent of the individual (or their parent, if the individual is a minor)
  • In response to a subpoena, court order or legal process, to the extent permitted or required by law
  • To protect the security and safety of individuals, data, assets and systems, consistent with applicable law
  • In connection the sale, joint venture or other transfer of some or all of its company or assets, subject to the provisions of this Privacy Notice
  • To investigate or address actual or suspected fraud or other illegal activities
  • To exercise its legal rights, including enforcement of the Terms of Use for this site or another contract
  • To affiliated Pearson companies and other companies and organizations who perform work for Pearson and are obligated to protect the privacy of personal information consistent with this Privacy Notice
  • To a school, organization, company or government agency, where Pearson collects or processes the personal information in a school setting or on behalf of such organization, company or government agency.


This web site contains links to other sites. Please be aware that we are not responsible for the privacy practices of such other sites. We encourage our users to be aware when they leave our site and to read the privacy statements of each and every web site that collects Personal Information. This privacy statement applies solely to information collected by this web site.

Requests and Contact

Please contact us about this Privacy Notice or if you have any requests or questions relating to the privacy of your personal information.

Changes to this Privacy Notice

We may revise this Privacy Notice through an updated posting. We will identify the effective date of the revision in the posting. Often, updates are made to provide greater clarity or to comply with changes in regulatory requirements. If the updates involve material changes to the collection, protection, use or disclosure of Personal Information, Pearson will provide notice of the change through a conspicuous notice on this site or other appropriate way. Continued use of the site after the effective date of a posted revision evidences acceptance. Please contact us if you have questions or concerns about the Privacy Notice or any objection to any revisions.

Last Update: November 17, 2020