.TH erlsrv 1 "erts 12.2" "Ericsson AB" "User Commands" .SH NAME erlsrv \- Run the Erlang emulator as a service on Windows .SH DESCRIPTION .LP This utility is specific to Windows NT/2000/XP (and later versions of Windows)\&. It allows Erlang emulators to run as services on the Windows system, allowing embedded systems to start without any user needing to log on\&. The emulator started in this way can be manipulated through the Windows services applet in a manner similar to other services\&. .LP Notice that \fIerlsrv\fR\& is not a general service utility for Windows, but designed for embedded Erlang systems\&. .LP \fIerlsrv\fR\& also provides a command-line interface for registering, changing, starting, and stopping services\&. .LP To manipulate services, the logged on user is to have administrator privileges on the machine\&. The Erlang machine itself is (default) run as the local administrator\&. This can be changed with the Services applet in Windows\&. .LP The processes created by the service can, as opposed to normal services, be "killed" with the task manager\&. Killing an emulator that is started by a service triggers the "OnFail" action specified for that service, which can be a reboot\&. .LP The following parameters can be specified for each Erlang service: .RS 2 .TP 2 .B \fIStopAction\fR\&: Tells \fIerlsrv\fR\& how to stop the Erlang emulator\&. Default is to kill it (Win32 TerminateProcess), but this action can specify any Erlang shell command that will be executed in the emulator to make it stop\&. The emulator is expected to stop within 30 seconds after the command is issued in the shell\&. If the emulator is not stopped, it reports a running state to the service manager\&. .TP 2 .B \fIOnFail\fR\&: Can be one of the following: .RS 2 .TP 2 .B \fIreboot\fR\&: The Windows system is rebooted whenever the emulator stops (a more simple form of watchdog)\&. This can be useful for less critical systems, otherwise use the heart functionality to accomplish this\&. .TP 2 .B \fIrestart\fR\&: Makes the Erlang emulator be restarted (with whatever parameters are registered for the service at the occasion) when it stops\&. If the emulator stops again within 10 seconds, it is not restarted to avoid an infinite loop, which could hang the Windows system\&. .TP 2 .B \fIrestart_always\fR\&: Similar to \fIrestart\fR\&, but does not try to detect cyclic restarts; it is expected that some other mechanism is present to avoid the problem\&. .TP 2 .B \fIignore\fR\& (the default): Reports the service as stopped to the service manager whenever it fails; it must be manually restarted\&. .RE .RS 2 .LP On a system where release handling is used, this is always to be set to \fIignore\fR\&\&. Use \fIheart\fR\& to restart the service on failure instead\&. .RE .TP 2 .B \fIMachine\fR\&: The location of the Erlang emulator\&. The default is the \fIerl\&.exe\fR\& located in the same directory as \fIerlsrv\&.exe\fR\&\&. Do not specify \fIwerl\&.exe\fR\& as this emulator, it will not work\&. .RS 2 .LP If the system uses release handling, this is to be set to a program similar to \fIstart_erl\&.exe\fR\&\&. .RE .TP 2 .B \fIEnv\fR\&: Specifies an \fIextra\fR\& environment for the emulator\&. The environment variables specified here are added to the system-wide environment block that is normally present when a service starts up\&. Variables present in both the system-wide environment and in the service environment specification will be set to the value specified in the service\&. .TP 2 .B \fIWorkDir\fR\&: The working directory for the Erlang emulator\&. Must be on a local drive (no network drives are mounted when a service starts)\&. Default working directory for services is \fI%SystemDrive%%SystemPath%\fR\&\&. Debug log files will be placed in this directory\&. .TP 2 .B \fIPriority\fR\&: The process priority of the emulator\&. Can be one of the following: .RS 2 .TP 2 .B \fIrealtime\fR\&: Not recommended, as the machine will possibly be inaccessible to interactive users\&. .TP 2 .B \fIhigh\fR\&: Can be used if two Erlang nodes are to reside on one dedicated system and one is to have precedence over the other\&. .TP 2 .B \fIlow\fR\&: Can be used if interactive performance is not to be affected by the emulator process\&. .TP 2 .B \fIdefault\fR\& (the default>: .RE .TP 2 .B \fISName or Name\fR\&: Specifies the short or long node name of the Erlang emulator\&. The Erlang services are always distributed\&. Default is to use the service name as (short) nodename\&. .TP 2 .B \fIDebugType\fR\&: Specifies that output from the Erlang shell is to be sent to a "debug log"\&. The log file is named \fI\&.debug\fR\& or \fI\&.debug\&.\fR\&, where is an integer from 1 through 99\&. The log file is placed in the working directory of the service (as specified in \fIWorkDir\fR\&)\&. .RS 2 .LP Can be one of the following: .RE .RS 2 .TP 2 .B \fInew\fR\&: Uses a separate log file for every invocation of the service (\fI\&.debug\&.\fR\&)\&. .TP 2 .B \fIreuse\fR\&: Reuses the same log file (\fI\&.debug\fR\&)\&. .TP 2 .B \fIconsole\fR\&: Opens an interactive Windows console window for the Erlang shell of the service\&. Automatically disables the \fIStopAction\fR\&\&. A service started with an interactive console window does not survive logouts\&. \fIOnFail\fR\& actions do not work with debug consoles either\&. .TP 2 .B \fInone\fR\& (the default): The output of the Erlang shell is discarded\&. .RE .LP .RS -4 .B Note: .RE The \fIconsole\fR\& option is \fInot\fR\& intended for production\&. It is \fIonly\fR\& a convenient way to debug Erlang services during development\&. .LP The \fInew\fR\& and \fIreuse\fR\& options might seem convenient in a production system, but consider that the logs grow indefinitely during the system lifetime and cannot be truncated, except if the service is restarted\&. .LP In short, the \fIDebugType\fR\& is intended for debugging only\&. Logs during production are better produced with the standard Erlang logging facilities\&. .TP 2 .B \fIArgs\fR\&: Passes extra arguments to the emulator startup program \fIerl\&.exe\fR\& (or \fIstart_erl\&.exe\fR\&)\&. Arguments that cannot be specified here are \fI-noinput\fR\& (\fIStopActions\fR\& would not work), \fI-name\fR\&, and \fI-sname\fR\& (they are specified in any way)\&. The most common use is for specifying cookies and flags to be passed to \fIinit:boot()\fR\& (\fI-s\fR\&)\&. .TP 2 .B \fIInternalServiceName\fR\&: Specifies the Windows-internal service name (not the display name, which is the one \fIerlsrv\fR\& uses to identify the service)\&. .RS 2 .LP This internal name cannot be changed, it is fixed even if the service is renamed\&. \fIerlsrv\fR\& generates a unique internal name when a service is created\&. It is recommended to keep to the default if release handling is to be used for the application\&. .RE .RS 2 .LP The internal service name can be seen in the Windows service manager if viewing \fIProperties\fR\& for an Erlang service\&. .RE .TP 2 .B \fIComment\fR\&: A textual comment describing the service\&. Not mandatory, but shows up as the service description in the Windows service manager\&. .RE .LP The naming of the service in a system that uses release handling must follow the convention \fINodeName\fR\&_\fIRelease\fR\&, where \fINodeName\fR\& is the first part of the Erlang node name (up to, but not including the "@") and \fIRelease\fR\& is the current release of the application\&. .SH EXPORTS .LP .B erlsrv {set | add} [] .br .RS .LP The \fIset\fR\& and \fIadd\fR\& commands modifies or adds an Erlang service, respectively\&. The simplest form of an \fIadd\fR\& command is without any options in which case all default values (described above) apply\&. The service name is mandatory\&. .LP Every option can be specified without parameters, the default value is then applied\&. Values to the options are supplied \fIonly\fR\& when the default is not to be used\&. For example, \fIerlsrv set myservice -prio -arg\fR\& sets the default priority and removes all arguments\&. .LP Service options: .RS 2 .TP 2 .B \fI-st[opaction] []\fR\&: Defines the \fIStopAction\fR\&, the command given to the Erlang shell when the service is stopped\&. Default is none\&. .TP 2 .B \fI-on[fail] [{reboot | restart | restart_always}]\fR\&: The action to take when the Erlang emulator stops unexpectedly\&. Default is to ignore\&. .TP 2 .B \fI-m[achine] []\fR\&: The complete path to the Erlang emulator\&. Never use the \fIwerl\fR\& program for this\&. Defaults to the \fIerl\&.exe\fR\& in the same directory as \fIerlsrv\&.exe\fR\&\&. When release handling is used, this is to be set to a program similar to \fIstart_erl\&.exe\fR\&\&. .TP 2 .B \fI-e[nv] [[=]] \&.\&.\&.\fR\&: Edits the environment block for the service\&. Every environment variable specified is added to the system environment block\&. If a variable specified here has the same name as a system-wide environment variable, the specified value overrides the system-wide\&. Environment variables are added to this list by specifying = and deleted from the list by specifying alone\&. The environment block is automatically sorted\&. Any number of \fI-env\fR\& options can be specified in one command\&. Default is to use the system environment block unmodified (except for two additions, see section Environment below)\&. .TP 2 .B \fI-w[orkdir] []\fR\&: The initial working directory of the Erlang emulator\&. Defaults to the system directory\&. .TP 2 .B \fI-p[riority] [{low|high|realtime}]\fR\&: The priority of the Erlang emulator\&. Default to the Windows default priority\&. .TP 2 .B \fI{-sn[ame] | -n[ame]} []\fR\&: The node name of the Erlang machine\&. Distribution is mandatory\&. Defaults to \fI-sname \fR\&\&. .TP 2 .B \fI-d[ebugtype] [{new|reuse|console}]\fR\&: Specifies where shell output is to be sent\&. Default is that shell output is discarded\&. To be used only for debugging\&. .TP 2 .B \fI-ar[gs] []\fR\&: Extra arguments to the Erlang emulator\&. Avoid \fI-noinput\fR\&, \fI-noshell\fR\&, and \fI-sname\fR\&/\fI-name\fR\&\&. Default is no extra arguments\&. Remember that the services cookie file is not necessarily the same as the interactive users\&. The service runs as the local administrator\&. Specify all arguments together in one string, use double quotes (") to specify an argument string containing spaces, and use quoted quotes (\\") to specify a quote within the argument string if necessary\&. .TP 2 .B \fI-i[nternalservicename] []\fR\&: \fIOnly\fR\& allowed for \fIadd\fR\&\&. Specifies a Windows-internal service name for the service, which by default is set to something unique (prefixed with the original service name) by \fIerlsrv\fR\& when adding a new service\&. Specifying this is a purely cosmethic action and is \fInot\fR\& recommended if release handling is to be performed\&. The internal service name cannot be changed once the service is created\&. The internal name is \fInot\fR\& to be confused with the ordinary service name, which is the name used to identify a service to \fIerlsrv\fR\&\&. .TP 2 .B \fI-c[omment] []\fR\&: Specifies a textual comment describing the service\&. This comment shows up as the service description in the Windows service manager\&. .RE .RE .LP .B erlsrv {start | start_disabled | stop | disable | enable} .br .RS .LP These commands are only added for convenience, the normal way to manipulate the state of a service is through the control panels services applet\&. .LP The \fIstart\fR\& and \fIstop\fR\& commands communicates with the service manager for starting and stopping a service\&. The commands wait until the service is started or stopped\&. When disabling a service, it is not stopped, the disabled state does not take effect until the service is stopped\&. Enabling a service sets it in automatic mode, which is started at boot\&. This command cannot set the service to manual\&. .LP The \fIstart_disabled\fR\& command operates on a service regardless of if it is enabled/disabled or started/stopped\&. It does this by first enabling it (regardless of if it is enabled or not), then starting it (if not already started), and then disabling it\&. The result is a disabled but started service, regardless of its earlier state\&. This is useful for starting services temporarily during a release upgrade\&. The difference between using \fIstart_disabled\fR\& and the sequence \fIenable\fR\&, \fIstart\fR\&, and \fIdisable\fR\& is that all other \fIerlsrv\fR\& commands are locked out during the sequence of operations in \fIstart_disable\fR\&, making the operation atomic from an \fIerlsrv\fR\& user\&'s point of view\&. .RE .LP .B erlsrv remove .br .RS .LP Removes the service completely with all its registered options\&. It is stopped before it is removed\&. .RE .LP .B erlsrv list [] .br .RS .LP If no service name is specified, a brief listing of all Erlang services is presented\&. If a service name is supplied, all options for that service are presented\&. .RE .LP .B erlsrv help .br .RS .LP Displays a brief help text\&. .RE .SH "ENVIRONMENT" .LP The environment of an Erlang machine started as a service contains two special variables: .RS 2 .TP 2 .B \fIERLSRV_SERVICE_NAME\fR\&: The name of the service that started the machine\&. .TP 2 .B \fIERLSRV_EXECUTABLE\fR\&: The full path to the \fIerlsrv\&.exe\fR\&, which can be used to manipulate the service\&. This comes in handy when defining a heart command for your service\&. .RE .LP A command file for restarting a service looks as follows: .LP .nf @echo off %ERLSRV_EXECUTABLE% stop %ERLSRV_SERVICE_NAME% %ERLSRV_EXECUTABLE% start %ERLSRV_SERVICE_NAME% .fi .LP This command file is then set as heart command\&. .LP The environment variables can also be used to detect that we are running as a service and make port programs react correctly to the control events generated on logout (see the next section)\&. .SH "PORT PROGRAMS" .LP When a program runs in the service context, it must handle the control events that are sent to every program in the system when the interactive user logs off\&. This is done in different ways for programs running in the console subsystem and programs running as window applications\&. An application running in the console subsystem (normal for port programs) uses the win32 function \fISetConsoleCtrlHandler\fR\& to register a control handler that returns \fItrue\fR\& in answer to the \fICTRL_LOGOFF_EVENT\fR\& and \fICTRL_SHUTDOWN_EVENT\fR\& events\&. Other applications only forward \fIWM_ENDSESSION\fR\& and \fIWM_QUERYENDSESSION\fR\& to the default window procedure\&. .LP A brief example in C of how to set the console control handler: .LP .nf #include /* ** A Console control handler that ignores the log off events, ** and lets the default handler take care of other events. */ BOOL WINAPI service_aware_handler(DWORD ctrl){ if(ctrl == CTRL_LOGOFF_EVENT) return TRUE; if(ctrl == CTRL_SHUTDOWN_EVENT) return TRUE; return FALSE; } void initialize_handler(void){ char buffer[2]; /* * We assume we are running as a service if this * environment variable is defined. */ if(GetEnvironmentVariable("ERLSRV_SERVICE_NAME",buffer, (DWORD) 2)){ /* ** Actually set the control handler */ SetConsoleCtrlHandler(&service_aware_handler, TRUE); } } .fi .SH "NOTES" .LP Although the options are described in a Unix-like format, the case of the options or commands is not relevant, and both character "/" and "-" can be used for options\&. .LP Notice that the program resides in the emulator\&'s \fIbin\fR\& directory, not in the \fIbin\fR\& directory directly under the Erlang root\&. The reasons for this are the subtle problem of upgrading the emulator on a running system, where a new version of the runtime system should not need to overwrite existing (and probably used) executables\&. .LP To manipulate the Erlang services easily, put the \fI\\erts-\\bin\fR\& directory in the path instead of \fI\\bin\fR\&\&. The \fIerlsrv\fR\& program can be found from inside Erlang by using the \fIos:find_executable/1\fR\& Erlang function\&. .LP For release handling to work, use \fIstart_erl\fR\& as the Erlang machine\&. As stated above, the service name is significant\&. .SH "SEE ALSO" .LP \fIstart_erl(1)\fR\&, \fIrelease_handler(3)\fR\&