System Launch and Monitor (slm)

The System Launch and Monitor (slm) is used to modify the launch sequence of applications and services without rebuilding the target image (or process management). The SLM if often used to launch complex applications consisting of many processes that must be started in a specific order.

Syntax:

slm [-aCkvV] [-D debug_mode] [-n subsystem_path] [-p priority]
    [-P search_path] [-r recovery_mode] [-R recovery_times]
    [-s comp_name] [-t polling_interval] [-T total_wait]
    [-x comp_name] config_file

Runs on:

QNX Neutrino

Options:

-a
Adopt running daemon processes. Use this option to integrate SLM with an existing system where some server processes may already be running. If you place component entries for all relevant system processes in the configuration file, SLM will adopt these processes at startup as if it had launched them itself (and can thus control the processes via the command interface or restart them automatically if they terminate abnormally).
-C
In case of error, let slm continue to work rather than bail out.
-D debug_mode
Specify when to use the <SLM:debug> argument list (instead of the normal <SLM:args> list). One of: cmd (default), startup, or always. With cmd, the debug list is used only when the module is started with the -d option. With startup, all components launched at startup (see the -s option) will initially use the debug list, but will then honor the -d option of subsequent restarts. With always, the debug list is always used.
-k
Control whether PROCMGR_EVENT_PATHSPACE and PROCMGR_EVENT_DAEMON_DEATH system events should be used to kick the normally poll-driven waitfor and stop handling. Since these events are also used by other processing, each event trigger may require an additional amount of unrelated activity, but generally this is faster than the default polling periods in detecting process state changes. Using these system events is enabled by default; specify -k if you don't want to use them.
-n subsystem_path
Set the access point (default is /dev/slm) for client applications to write control and query commands.
-p priority
Set the priority of the SLM server threads (default is 30).
-P search_path
Set the search path for executables (default is $PATH). When launching a process, SLM looks in the search path to find the executable if the corresponding command tag doesn't contain a full path.
-r recovery_mode
Set the recovery mode for components monitored by SLM. One of: none (default), stop, or replace. The action specified with the -r option is performed when a component terminates abnormally if that component doesn't override this setting in its repair tag.
-R
Set the maximum number of times to attempt recovery (default is 2 times per minute).
-s comp_name
Name a component or module to launch at startup. For convenience, you can use the built-in modules "all" and "none" (default is "all").
-t polling_interval
Set the polling interval in milliseconds for the wait property. Default is 100.
-T total_wait
Set the total wait time in milliseconds. Default is 50000.
-v
Increase output verbosity (messages are written to sloginfo). The -v option is cumulative; each additional v adds a level of verbosity, up to 7 levels.
-V
Log output messages to the console (as well as sloginfo).
-x comp_name
Name a component or module to terminate at shutdown. For convenience, you can use the built-in modules "all" and "none" (default is "all").

Description:

The SLM service starts processes required for your system. SLM is started from startup.sh, which runs early in the boot sequence. The SLM service is often used to launch complex applications consisting of multiple processes that must be started in a specific order. In the SLM command line inside startup.sh, you must specify a configuration file, but all the other parameters are optional.

SLM is a utility controlled by a configuration file. The configuration file specifies any interprocess dependencies, the processes to run, and the process properties. For example, suppose a multimedia application needs the services of the audio subsystem and the database server, which in turn requires the Persistent Publish/Subscribe (PPS) service. When SLM learns of these one-way dependencies when reading the configuration file, the service internally constructs a directed acyclic graph (DAG). The DAG represents the workflow of the underlying processes and is sorted to produce a partial ordering for scheduling the processes so that all control-flow dependencies are respected. In this example, SLM would first verify that PPS is running before starting the database server, and then check that the database server is running before starting the multimedia application.

Control and query commands

Client applications can control SLM by writing commands to the /dev/slm interface.

Control commands can start, stop, restart, or replace a specified module or component. When you start a component, SLM will start any dependencies (that aren't already running) and wait for them as required. When you stop a component, SLM first stops any dependents on the component. Restarting is a sequential composition of stop and start operations and is typically applied to set a specific high-level module state. Replacing will stop and relaunch a component and then restart any currently active components that had a dependency on that component. This is typically applied to update a low-level component process.

Query commands can list the dependencies (depend), running components (active), or components that terminated abnormally (dead). Command lines consist of the command, any options, and a module or component name, if appropriate.
Note:

Only the system superuser (UID 0) can execute the control and query commands (except active and depend).

The following table summarizes the control and query commands:
Command Options Description
active -v List the active (running) components.
dead -v -w List the dead (faulted) components.
depend -s -u -v List dependencies or dependents for the specified component.
start -d -v -x Start the specified component.
stop -s -v -x Stop the specified component.
restart -d -s -v -x Stop, then start the specified component.
replace -d -s -v -x Update the specified component.
The following table describes all the options:
Option Description
-d Debug mode: start components with their debug argument list.
-s Stateless: ignore any stateless dependencies when stopping components.
-u Used by: list components that depend on the specified component.
-v Verbose: give details of each action performed when responding to a command.
-w Wait: block until a process terminates abnormally.
-x Explain: list the required actions but don't perform them.

Command example

Following execution of a command written to /dev/slm, the results are available to be read from the same file descriptor. Here's a simple example (with no error handling):
int    slm;
char   text[128];

slm = open("/dev/slm", O_RDWR);
write(slm, "start -v all", 12);
while (read(slm, text, sizeof(text)) > 0)
printf("%s\n", text);
close(slm);

Issuing commands via the slmctl utility

Besides writing control/query commands programmatically, you can use the slmctl utility to send SLM commands (via the command line or typed interactively).

The utility displays the results of each action in a line describing the operation on the specified component or module as follows:
Utility output Meaning
START component pid|error Component was started.
start component Component already active (no errors).
WAIT component error Waiting for component.
wait component Component already active (no errors).
STOP component error Component stopped.
stop component Component already inactive.
BEGIN module Encapsulation of multiple components.
END module error Reported only via sloginfo, not slmctl.

SLM configuration file

SLM uses an XML configuration file to determine the appropriate order for scheduling processes. The configuration file lists all the processes for SLM to manage, any dependencies between the processes, the commands for launching the processes, and other properties.

$QNX_DEPLOYMENT_WORKSPACE/target/product/ADAS/

The default files provided are:

slm-config-all.xml
Configures services common to all hardware platforms. Located in: etc/.
slm-config-modules.xml
An example of how to add new modules. Located in: etc/. This file is included in slm-config-all.xml.
slm-config-platform.xml
Platform-specific services, such as board-specific drivers. Located in: boards/platform.variant/etc/

Configuration file structure

The root XML element of the configuration file is the system tag. All element names start with SLM:, so the root element (and the outline of the file) looks like this:

<SLM:system>
    -- component and module descriptions --
</SLM:system>

Sample configuration file

Suppose you want to automate the setup of your system's IP connectivity. This would require running io-pkt, which creates an IP socket for network traffic, and then running ifconfig to bind an IP address to the socket. You can create a module to include two components that correspond to the two services, and then describe the dependency of ifconfig on io-pkt in the component entries. The XML file would then look like this:

<SLM:system>
    <SLM:component name="io-pkt">
        <SLM:command>/sbin/io-pkt-v6-hc</SLM:command>
        <SLM:args>-ptcpip stacksize=8192</SLM:args>
        <SLM:waitfor wait="pathname">/dev/socket</SLM:waitfor>
    </SLM:component>
    <SLM:component name="ifconfig">
        <SLM:depend>io-pkt</SLM:depend>
        <SLM:command>/sbin/ifconfig</SLM:command>
        <SLM:args>en0 192.168.1.5 up</SLM:args>
        <SLM:waitfor wait="exits"></SLM:waitfor>
    </SLM:component>
    <SLM:module name="net-setup">
        <SLM:member>io-pkt</SLM:member>
        <SLM:member>ifconfig</SLM:member>
    </SLM:module>
</SLM:system>

Components

A process managed by SLM is represented by a component. You must provide a component name (usually based on the process name) that will be used within the configuration file when specifying interprocess dependencies or membership in a group of components.

All component tags are listed in the root element and contain other tags that describe the properties of individual components. The component tag syntax is as follows:
<SLM:component name="mcd">
    -- component properties --
</SLM:component>

The following table describes the component tags:

Tag Attribute Value(s) Description
args   command_args The list of command-line arguments to provide the binary executable.
cd   dir_name

The directory to switch into when launching the process; this directory becomes the process's working directory ($CWD).

command launch [ bg[,nohup] ] Controls process creation.
  pathname The full path of the binary executable (e.g., /usr/bin/mcd).
  builtin
The name of a built-in SLM command. Options are:
  • mkdir—creates one or more directories. List the directories to create in the args element.
  • no_op—does nothing, but allows waiting for a filepath. This mechanism can be used to detect whether a process started outside of SLM is ready.
  • pathmgr_symlink—creates one or more fast kernel symlinks. List the symlinks to create in the args element.
debug   command_args

An alternative list of command-line arguments to provide the binary executable when SLM is run in debug mode. This list might contain options (such as -v to increase verbosity).

depend state [ session | stateless ]

A component may need other services to be active before the component can run. Any prerequisites must be expressed as dependencies.

There are two forms of dependency: session (stateful) and stateless. With session dependency (the default), a client/server relationship is assumed; the server stores state information on all its clients. In this model, if the server must be stopped or restarted, then all its clients must be stopped.

With stateless dependency, the server doesn't maintain any client information, so it's not necessary to restart clients if the server is restarted.

  component_name Name of the prerequisite component. A component can have zero, one, or many dependencies.
Note: You must define a separate tag for each dependency.

SLM won't start a component until all the prerequisites are running.

priority   priority_policy An alphanumeric value indicating the priority level and scheduling policy to assign the process (e.g., 10r).
repair   [ default | none | stop | replace ]
Specifies the action to take if the component terminates abnormally:
  • default—tells SLM to perform the action specified by the -r command-line option
  • none—SLM takes no recovery action
  • stop—SLM stops any other components that depend on the component that failed
  • replace—SLM restarts the failed component
stderr iomode [ w[+] | a[+] ] The access mode: overwrite (w), read and overwrite (w+), append (a), or read and append (a+).
  filename Name of the file for redirecting standard error (stderr).
stdin iomode [ r[+] ] The access mode: read only (r) or read and write (r+).
  filename Name of the file for redirecting standard input (stdin).
stdout iomode [ w | a ] The access mode: overwrite (w) or append (a).
  filename Name of the file for redirecting standard output (stdout).
stop stop [ none | signal ]

The signal setting (the default) causes SLM to send a signal to the underlying process. The none setting disables the signaling; in this case, SLM takes no action to stop a process.

child [ self | before | after ]

For any process launched by SLM, its child processes are out of SLM's direct control. You can specify the shutdown of these child processes as relative to when the SLM-controlled parent process is terminated. The settings are: self (the default), before, and after.

  data
Contains the signal number to send the process to stop it. By default, SIGTERM is sent, but you can change this to any signal. If repeated failed attempts to stop the process fail, SIGKILL is sent.
Note: This tag value isn't needed when the stop attribute is set to none.
user   uid:gid The user ID and group ID to assign to the underlying process. The two strings are separated by a colon (e.g., jgarvey:techies).
waitfor wait [ none | delay | pathname | exits | blocks ]
Once a component has been launched, SLM can wait for that component to set itself up before starting any dependent components. Values:
  • none (the default)—causes SLM to start other components immediately
  • delay—SLM pauses for the specified number of milliseconds
  • pathname—SLM probes for the appearance of the specified pathname
  • exits—SLM waits for the process to finish
  • blocks—SLM waits for a specified thread in the process to reach the RECV-blocked state
polltime poll_time:timeout_time Use with wait="pathname" or wait="exits" to specify a polling interval and total wait time (both in milliseconds) that override the global values. For example, polltime="100:20000" results in polling every 100 milliseconds and timing out after 20 seconds.
  data Contains data specific to the specified wait condition. For example, for delay, the value could be 5000 (for a 5s delay).
Note:

Only the command property is mandatory—all processes must have a path to the binary executable. The remaining properties are optional.

Modules

You can group components into modules. The processes within a module could make up a subsystem or could be used to establish a set of system states, such as a base level of operation and various higher levels. Modules must be named so they can be internally referenced. Each module must be described in a tag, as follows:

<SLM:module name="device_monitors">
    -- module description --
</SLM:module>

To list the components within a module, use the member tag. There are no attributes for member tags; the tag values refer to member components by the internal names defined in their respective component tags.

Note:

You can include multiple components in a module by using one member tag with wildcards in the component names. For example, you can write:

<SLM:member>devb-*</SLM:member>

Modules can have dependencies on components or on other modules. Each dependency must be specified in a depend tag within the module tag.

Components and modules may be specified in any order in the XML configuration file, but SLM will raise an error if any circular dependencies are found.

Example: SLM configuration to use file camera immediately

This example describes how to change the default version of the slm-config-platform.xml file provided on the reference image to support file cameras. The slm-config-platform.xml file can be changed by copying over different versions of the file, which allows you to easily change your system for different camera configurations. We refer to the default version as the one that's a copy of slm-config-platform-default.xml. The file is located in the /etc/ directory on the reference image.

To use this configuration, you must ensure that you have file cameras specified in the camera configuration file. For more information, see the “Example” section for file cameras in the Camera configuration file section.

The SLM configuration changes listed here are changes you must make to the slm-config-platform-default.xml file. To configure your SLM configuration file for a file camera, here's what you would do:
  • Move the syslink_daemon component before the camera_service component. The syslink_daemon component is used for video encoding and decoding while the camera_service component starts the camera service.Decoding must be available before the camera service runs.
  • In the syslink_daemon component, remove the dependency to wait until the camera component comes up.
  • In the camera_service component, add a dependency to wait until the syslink_daemon component comes up.
The modified version of the slm-config-platform.xml file should look like this:
...
<SLM:component name="symlink_wifi">
    <SLM:command launch="builtin">pathmgr_symlink</SLM:command>
    <SLM:args>/var/etc/ap_pps_mhs.conf /base/etc/ap_pps_mhs.conf;
                    /var/etc/wpa_pps.conf /base/etc/wpa_pps.conf;
                    /var/etc/wpa_supplicant.conf /base/etc/wpa_supplicant.conf</SLM:args>
</SLM:component>
...
...
<SLM:component name="syslink_daemon">
   <SLM:command>/base/bin/ipc</SLM:command>
   <SLM:args>IPU2 /lib/firmware/dra7xx-m4-ipu2.xem4</SLM:args>
   <SLM:waitfor wait="pathname">/dev/ipc</SLM:waitfor>
</SLM:component>

<SLM:component name="camera_service">
   <SLM:command>/base/bin/camera</SLM:command>
   <SLM:args>-U 521:521 -r /accounts/1000/shared/camera -v -c /etc/system/config/camera.conf</SLM:args>
   <SLM:depend>syslink_daemon</SLM:depend>
</SLM:component>

<SLM:component name="camera_mux2x2">
    <SLM:command>/base/usr/bin/camera_mux2x2</SLM:command>
</SLM:component>

<SLM:component name="usb">
    <SLM:command>io-usb</SLM:command>
    <SLM:args>-vvv -c -d omap5-xhci ioport=0x48890000,irq=108,ioport=0x488d0000,irq=110</SLM:args>
    <SLM:waitfor wait="pathname">/dev/io-usb/io-usb</SLM:waitfor>
    <SLM:depend>camera</SLM:depend>
    <SLM:stop stop="signal">SIGTERM</SLM:stop>
</SLM:component>

<SLM:component name="camera">
    <SLM:command launch="builtin">no_op</SLM:command>
    <SLM:waitfor wait="pathname">/dev/shmem/camera4-start.run</SLM:waitfor>
</SLM:component>
...
...
<SLM:component name="trace_syslink">
    <SLM:command>ipc_trace_daemon</SLM:command>
    <SLM:stop stop="signal">SIGTERM</SLM:stop>
    <SLM:depend>syslink_daemon</SLM:depend>
    <SLM:stdout>/dev/null</SLM:stdout>
    <SLM:stderr>/dev/null</SLM:stderr>
</SLM:component>
...

Example: SLM configuration for USB cameras to boot immediately

This example describes how to change the default version of the slm-config-platform.xml file provided on the reference image to support USB cameras. The slm-config-platform.xml file can be changed by copying over different versions of the file, which allows you to easily change your system for different camera configurations. We refer to the default version as the one that's a copy of slm-config-platform-default.xml file. The file is located in the /etc/ directory on the reference image.

To use this configuration, you must ensure that you have USB cameras configured in the camera configuration file. For more information, see the “Example: Camera configuration file for USB camera” section in the Camera configuration file section.

In this situation, you must ensure that the USB driver starts before the Camera Service and Camera components start. For that reason, you would specify that the Camera Service (camera_service component) depends on the USB component. If you weren't using a USB camera, then you shouldn't have the camera component depend on the USB component starting first.

The SLM configuration changes listed here are changes you must make to the default version of the slm-config-platform.xml file. To configure your SLM configuration file for a USB camera, here's what you would do:
  • Move the usb component before the camera_service component. The usb component starts the USB drivers while the camera_service component starts the camera service.
  • In the usb component, remove the dependency to wait until the camera component comes up.
  • In camera_service component, add a dependency to wait until the usb component comes up.
The modified version of the slm-config-platform.xml file should look like this:
...
...
<SLM:component name="symlink_wifi">
    <SLM:command launch="builtin">pathmgr_symlink</SLM:command>
    <SLM:args>/var/etc/ap_pps_mhs.conf /base/etc/ap_pps_mhs.conf; 
                    /var/etc/wpa_pps.conf /base/etc/wpa_pps.conf; 
                    /var/etc/wpa_supplicant.conf /base/etc/wpa_supplicant.conf</SLM:args>
</SLM:component>

<SLM:component name="shmemallocator">
    <SLM:command>/base/bin/shmemallocator</SLM:command>
</SLM:component>

<SLM:component name="resarb">
    <SLM:command>/base/bin/resarb</SLM:command>
    <SLM:args>-vvvvv</SLM:args>
</SLM:component>
    
<SLM:component name="usb">
    <SLM:command>io-usb</SLM:command>
    <SLM:args>-vvv -c -d omap5-xhci ioport=0x48890000,irq=108,ioport=0x488d0000,irq=110</SLM:args>
    <SLM:waitfor wait="pathname">/dev/io-usb/io-usb</SLM:waitfor>
    <SLM:stop stop="signal">SIGTERM</SLM:stop>
</SLM:component>

<SLM:component name="camera_service">
    <SLM:command>/base/bin/camera</SLM:command>
    <SLM:args>-U 521:521 -r /accounts/1000/shared/camera -v -c 
                    /etc/system/config/camera.conf</SLM:args> 
    <SLM:depend>usb</SLM:depend>
</SLM:component>

<SLM:component name="camera_mux2x2">
    <SLM:command>/base/usr/bin/camera_mux2x2</SLM:command>
</SLM:component>

<SLM:component name="camera">
    <SLM:command launch="builtin">no_op</SLM:command>
    <SLM:waitfor wait="pathname">/dev/shmem/camera4-start.run</SLM:waitfor>
</SLM:component>
...
...
...
            

Example: SLM configuration to have encoding and decoding start immediately

This example describes how to change the default version of the slm-config-platform.xml file provided on the reference image to encode/decode video immediately after the target boots. The slm-config-platform.xml file can be changed by copying over different versions of the file, which allows you to easily change your system for different camera configurations. We refer to the default version as the one that's a copy of slm-config-platform-default.xml file. The file is located in the /etc/ directory on the reference image.

To use this configuration, you must ensure that you have a USB, parallel, or FPD-Link III camera configured. For more information, see the examples in the Camera configuration file section.

The default version of the slm-config-platform.xml file on the reference image is configured to provide encoding/decoding of video at a later time. To configure your SLM configuration file so that encoding/decoding is available as soon as the target completes booting, perform the following steps to the default version of the slm-config-platform.xml file:
  • Move the syslink_daemon component before the camera_service component. The syslink_daemon component is used for video encoding and decoding while the camera_service component starts the camera service.
  • In the syslink_daemon component, remove the dependency to wait until the camera component comes up.
  • In camera_service component, add a dependency to wait until the syslink_daemon component comes up.
The modified version of the slm-config-platform.xml file should look like this:
 <!-- VARIANT SPECIFIC ENTRIES -->

<SLM:component name="symlink_wifi">
    <SLM:command launch="builtin">pathmgr_symlink</SLM:command>
    <SLM:args>/var/etc/ap_pps_mhs.conf /base/etc/ap_pps_mhs.conf;
                    /var/etc/wpa_pps.conf /base/etc/wpa_pps.conf;
                    /var/etc/wpa_supplicant.conf /base/etc/wpa_supplicant.conf</SLM:args>
</SLM:component>

...
...
...
<SLM:component name="syslink_daemon">
   <SLM:command>/base/bin/ipc</SLM:command>
   <SLM:args>IPU2 /lib/firmware/dra7xx-m4-ipu2.xem4</SLM:args>
   <SLM:waitfor wait="pathname">/dev/ipc</SLM:waitfor>
</SLM:component>

<SLM:component name="camera_service">
   <SLM:command>/base/bin/camera</SLM:command>
   <SLM:args>-U 521:521 -r /accounts/1000/shared/camera -v -c /etc/system/config/camera.conf</SLM:args>
   <SLM:depend>syslink_daemon</SLM:depend>
</SLM:component>

<SLM:component name="camera_mux2x2">
    <SLM:command>/base/usr/bin/camera_mux2x2</SLM:command>
</SLM:component>

<SLM:component name="usb">
    <SLM:command>io-usb</SLM:command>
    <SLM:args>-vvv -c -d omap5-xhci ioport=0x48890000,irq=108,ioport=0x488d0000,irq=110</SLM:args>
    <SLM:waitfor wait="pathname">/dev/io-usb/io-usb</SLM:waitfor>
    <SLM:depend>camera</SLM:depend>
    <SLM:stop stop="signal">SIGTERM</SLM:stop>
</SLM:component>

<SLM:component name="camera">
    <SLM:command launch="builtin">no_op</SLM:command>
    <SLM:waitfor wait="pathname">/dev/shmem/camera4-start.run</SLM:waitfor>
</SLM:component>
...
...
...


<SLM:component name="trace_syslink">
    <SLM:command>ipc_trace_daemon</SLM:command>
    <SLM:stop stop="signal">SIGTERM</SLM:stop>
    <SLM:depend>syslink_daemon</SLM:depend>
    <SLM:stdout>/dev/null</SLM:stdout>
    <SLM:stderr>/dev/null</SLM:stderr>
</SLM:component>
...
...
...