- Introduction
- Booting a System
- The OpenBoot Environment
- The OpenBoot Architecture
- The OpenBoot Interface
- Getting Help in OpenBoot
- PROM Device Tree (Full Device Pathnames)
- OpenBoot NVRAM
- OpenBoot Security
- OpenBoot Diagnostics
- OpenBoot PROM Versions
- Booting a System
- The Kernel
- The init Phase
- System Shutdown
- Summary
- Suggested Readings and Resources
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:
id:runlevel:action:process
Table 3.23 provides a description of each field.
Table 3.23 Fields in the inittab File
Field |
Description |
id |
A unique identifier |
rstate |
The run level(s) |
action |
How the process is to be run |
process |
The name of the command to execute |
Valid action keywords are listed in Table 3.24:
Table 3.24 inittab action Field Values
Field |
Description |
sysinit |
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. |
powerfail |
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:
svc://localhost/network/inetd:default svc:/network/inetd:default network/inetd:default
An FMRI for a legacy service will have the following format:
lrc:/etc/rc3_d/S90samba
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
Event |
None |
Error |
Restart |
Refresh |
stop due to error |
no |
yes |
yes |
yes |
non-error stop |
no |
no |
yes |
yes |
refresh |
no |
no |
no |
yes |
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
Command |
Description |
inetadm |
Used to configure and view services controlled by the inetd daemon. Described in more detail in Chapter 8, "The Solaris Network Environment." |
svcadm |
Used to perform common service management tasks such as enabling, disabling, or restarting service instances. |
svccfg |
Used to display and manipulate the contents of the service configuration repository. |
svcprop |
Used to retrieve property values from the service configuration repository with output that is appropriate for use in shell scripts. |
svcs |
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:
STATE STIME FMRI 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:
- degradedThe service instance is enabled, but is running at a limited capacity.
- disabledThe service instance is not enabled and is not running.
- legacy_runThe 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.
- maintenanceThe service instance has encountered an error that must be resolved by the administrator.
- offlineThe service instance is enabled, but the service is not yet running or available to run.
- onlineThe service instance is enabled and has successfully started.
- uninitializedThis 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
STATE STIME FMRI 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:
STATE STIME FMRI 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:
STATE STIME FMRI 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:
STATE STIME FMRI 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:
STATE STIME FMRI 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:
STATE STIME FMRI online 16:07:08 svc:/network/ftp:default
The svcadm command allows the following subcommands:
- EnableEnables the service instances.
- DisableDisables the service instances.
- RestartRequests that the service instances be restarted.
- RefreshFor 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.
- ClearFor 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.
STEP BY STEP
3.2 Changing Milestones
- 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
- I'll check to see which milestone the system is currently running at:
- To start the transition to the single-user milestone, type
- Verify the current milestone with the following command:
- Finally, I'll bring the system backup to the multi-user-server milestone:
# 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
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.
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 #
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.
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.
STATE STIME FMRI 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.
STEP BY STEP
3.3 Enable the NFS Server Service
In the following example, I'll configure SMF to share the NFS resources on an NFS server.
- Log in as root or use a role that includes the Service Management rights profile.
- The NFS server services are not running as displayed by the following svcs command:
- 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:
- Enable the NFS service as follows:
- Verify that the NFS server service is running by typing:
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.
share -F nfs -o rw /data
svcadm enable svc:/network/nfs/server
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.
STEP BY STEP
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:
#!/sbin/sh case "$1" in ‘start’) /usr/local/legacyprog ;; ‘stop’) /usr/bin/pkill -x -u 0 legacyprog ;; *) echo "Usage: $0 { start | stop } " exit 1 ;; esac 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 "/usr/share/lib/xml/dtd/service_bundle.dtd.1"> <!-- ident "@(#)newservice.xml 1.2 04/09/13 SMI" --> <service_bundle type=’manifest’ name=’OPTnew:legacyservice’> <service name=’site/legacyservice’ type=’service’ version=’1’> <single_instance/> <dependency name=’usr’ type=’service’ grouping=’require_all’ restart_on=’none’> <service_fmri value=’svc:/system/filesystem/local’ /> </dependency> <dependent name=’newservice’ grouping=’require_all’ restart_on=’none’> <service_fmri value=’svc:/milestone/multi-user’ /> </dependent> <exec_method type=’method’ name=’start’ exec=’/lib/svc/method/legacyservice start’ timeout_seconds=’30’ /> <exec_method type=’method’ name=’stop’ exec=’/lib/svc/method/legacyservice stop’ timeout_seconds=’30’ /> <property_group name=’startd’ type=’framework’> <propval name=’duration’ type=’astring’ value=’transient’ /> </property_group> <instance name=’default’ enabled=’true’ /> <stability value=’Unstable’ /> <template> <common_name> <loctext xml:lang=’C’> New service </loctext> </common_name> </template> </service> </service_bundle>
Now let's take a closer look at the XML-based manifest file and the steps I took to create it.
- 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:
- 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
- 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:
- Define any dependencies for this service. I added the following entry to the manifest:
- 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:
- 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:
- Identify the service modelwill 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
- The next step is to create the instance name for the service by making the following entry:
- 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
- Once the manifest is complete, is a good idea to verify the syntax using the xmllint program as follows:
- 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:
- The service should now be visible using the svcs command as follows:
- You can also see which services the legacyservice depends on by using the svcs -d command as follows:
- As a final step, enable the service using the svcadm command as follows:
- At any time, I can view the properties of a service using the svccfg command as follows:
<?xml version="1.0"?> <!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1"> <!-- ident "@(#)newservice.xml 1.2 04/09/13 SMI" --> <service_bundle type='manifest' name='OPTnew:legacyservice'>
applicationHigher level applications, such as apache
milestoneCollections of other services, such as name-services
platformPlatform-specific services, such as Dynamic Reconfiguration daemons
systemSolaris system services, such as coreadm
deviceDevice-specific services
networkNetwork/Internet services, such as protocols
siteSite 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:
<service name='site/legacyservice' type='service' version='1'>
<single_instance />
<dependency name='usr' type='service' grouping='require_all' restart_on='none'> <service_fmri value='svc:/system/filesystem/local' /> </dependency>
The first entry states that the legacyservice requires the filesystem/local service.
<dependent name='testservice' grouping=require_all' restart_on='none'> <service_fmri value='svc:/milestone/multi-user' /> <dependent>
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:
<dependent name='legacyservice_syslog'
<exec_method type='method' name='start' exec='/lib/svc/method/legacyservice start' timeout_seconds='30' /> <exec_method type='method' name='stop' 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'.
Transient servicesThese 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 servicesThese services run for the lifetime of the child process, and are restarted when that process exits.
Contract servicesThese 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' /> </property_group>
<instance name='default' enabled='true' />
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":
<template> <common_name> <loctext xml:lang='C'> New service </loctext> </common_name> </template>
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
svccfg import /var/svc/manifest/site/legacyservice
# svcs legacyservice STATE STIME FMRI - svc:/site/legacyservice:default
svcs -d legacyservice STATE STIME FMRI online Sep_20 svc:/system/filesystem/local:default
svcadm -v enable legacyservice svc:/site/legacyservice:default enabled.
svccfg -v -s legacyservice
The system responds with the following prompt:
svc:/site/legacyservice>
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" svc:/site/legacyservice>
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) |
Description |
0 |
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. |
1 |
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. |
4 |
Alternative multi-user state (currently not used). |
5 |
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. |
6 |
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:
[K,S][#][filename]
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.
STEP BY STEP
3.5 Adding a Run Control Script
- Become the superuser.
- Add the script to the /etc/init.d directory:
- Create links to the appropriate rc<n>.d directory:
- Use the ls command to verify that the script has links in the specified directories:
# cp <filename> /etc/init.d # cd /etc/init.d # chmod 744 <filename> # chown root:sys <filename>
# ln <filename> /etc/rc2.d/S<nnfilename> # ln <filename> /etc/rc<n>.d/K<nnfilename>
# 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