# Using AMPL's Floating-License Manager, ampl_lic

The AMPL® floating-license manager, ampl_lic, permits sharing a license for AMPL and perhaps some solvers among several machines on a local network. One machine hosts the network license manager, and each machine to which licenses may float has a local license manager. Both managers are the same program,`ampl_lic` (or, on Microsoft systems, `ampl_lic.exe`). For programs (ampl and some solvers) that are licensed per machine, the local manager gets one license for the program and can start as many processes of the program as desired without talking further with the network manager. Licensed programs will attempt to start the license manager if it is not already running. On client machines, the license file "ampl.lic" determines which machine hosts the network manager, i.e., which machine is the license server. On the license server, ampl_lic looks for a license file named "ampl.netlic" first; if not found, it looks for "ampl.lic". The license file has a license string that involves the machine's fingerprint and indicates what the manager is permitted to do: how many licenses of what sort and to what IP addresses it can issue licenses. On client machines, ampl.lic merely needs to have one line of the form

MGR_IP = 192.168.1.131

where the IP address is that of the machine hosting the network license manager. (A quoted "hostname" should also work in place of a specific IP address.)

The license managers (both network and local) and licensed programs (ampl and perhaps some solvers) use a dedicated TCP port, which by default is port 5195, but which can be specified by a line of the form

PORT = 1234

in `ampl.lic`. You may need to adjust your firewall settings to permit use of the relevant ICP port.

Both ampl_lic and licensed programs look for `ampl.lic` (or, if $AMPL_LICFILE is set, for $AMPL_LICFILE) in their directory first, then in `$PATH`. If $AMPL_LICFILE is an absolute file name, then only that file is checked. Prior to 20051223, $AMPL_LICFILE, if set, was only sought in the current directory.

The network license manager needs to be started before a machine elsewhere can get a floating license. Running a licensed program on the machine hosting the network-license manager should cause the manager to start, but to avoid delays and messages about starting the license manager when invoking licensed programs, you may find it better to start the network license manager separately. On Linux or Unix systems, it can be started by an invocation of the form (in Bourne-shell notation)

`pwd`/ampl_lic

I.e., it must be started by a full path name (for security). The local managers can be started similarly -- with full pathnames -- once the network license manager is running. Both the network and local license managers must be started in directories where they can write "lock" and "state" files; these directories need not be on $PATH. (If not on $PATH, it is convenient to have another copy of ampl_lic on $PATH, with a one-line ampl.lic file, for use in the invocations discussed below, e.g., "ampl_lic status" and "ampl_lic checkout ...". On Linux and probably most Unix systems, the license manager (network or local) could be started by a little script in one of the directories of scripts that get run when the system boots. The resulting ampl_lic process could similarly be stopped by another such script, but since ampl_lic catches the SIGTERM signal that all running programs should get before the system shuts down, there is no need to worry about explicitly stopping ampl_lic. The managers do need to stop gracefully -- to write out the state of licenses they have or have given out and of licensed programs that are still running. One can also manually stop a manager by executing

ampl_lic stop

while licensed programs continue to run. Upon a subsequent manual invocation (``pwd`/ampl_lic`) or invocation of a licensed program (which will invoke ``pwd`/ampl_lic` if necessary), ampl_lic will read its saved-state file, check for licensed processes that are still running, and update its state accordingly. It then checks in with the network manager, which returns (among other things) a checksum of what it thinks is the local manager's state. The local manager then corrects the network manager's view if necessary.

On macOS systems, arranging for `ampl_lic` to start automatically is more complicated. A way that works at least with Mac OS X 10.7 is to add a file named `com.ampl.ampl_lic.plist`, owned by root, to directory `/Library/LaunchDaemons`. For example,
`<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.ampl.ampl_lic</string>
<key>ProgramArguments</key>
<array>
<string>/usr/local/ampl_lic/ampl_lic</string>
<string>--nofork</string>
<string>--sleep</string>
<string>10</string>
</array>
<key>WorkingDirectory</key>
<string>/usr/local/amp_lic</string>
<key>UserName</key>
<string>nobody</string>
<key>GroupName</key>
<string>nobody</string>
<key>RunAtLoad</key>
<true/>
</dict>
</plist>
`

Under MS Windows, if you or a licensed program starts `ampl_lic` directly, you will not be able to close the window in which the licensed program runs until `ampl_lic` is stopped. To avoid this inconvenience, you can install a "service" called "ampl_lic_service", which attempts to start ampl_lic when the system boots and to stop ampl_lic cleanly when the system is being shut down. Please initially make sure all goes well with an invocation of alic_run; this way, if your firewall settings need changing, at least Windows should present a pop-up message box about ampl_lic and the firewall. (Such a pop-up does not appear with ampl_lic installed as a service.)

On recent versions of MS Windows, such as Windows 7 and 8, and on some earlier versions, such as Vista, on which you have installed .Net 4.0, you can use amp_lic_setup.msi to install ampl_lic as a service, but the procedure is somewhat more cumbersome than that described below for Windows XP. To install ampl_lic as a service, first create C:\bin (if it does not already exist) and put a copy of ampl_lic.exe and ampl.lic or (on the license server) ampl.netlic there. If ampl_lic is still running due to an invocation of alic_run, explicitly stop it by invoking

`ampl_lic stop`

Then invoke ampl_lic_setup.msi. You will be given a chance to change the suggested installation directory. It is best not to do so. If you do change it, the installation may appear to work, but you might not be able to start the ampl_lic service. (Changing the installation directory to C:\bin does work on at least some systems.)

The service setup runs ampl_lic in the LocalService account, which has no special privileges; C:\bin must be writable by this account. You can run ampl_lic_setup.msi before adding ampl_lic.exe and either ampl.lic or ampl.netlic to C:\bin; the service installation will still work, but you will not be able to start ampl_lic until you have added the needed files to C:\bin. Once they are there and you have installed the ampl_lic service, you need to start the service. To do so, click the Start button, right-click Computer, click "Manage", expand "Services and Applications", right-click "ampl_lic_service", and click "Start". If you get a pop-up box that says "Could not start the ampl_lic_service service... Error 1053...", right-click the "ampl_lic_service" entry in the Services window; if the windows that appears has a "Log On" tab, click this tab and select "Allow service to interact with desktop". Then try again to start the service.

Once you are able to start ampl_lic from the "Services and Applications" window window, the service should start automatically when the system is rebooted. Because off the "delayed start" feature on some versions of Windows, it may take a couple of minutes for ampl_lic to start automatically, but you can manually start it sooner from the Services window if desired.

For the ampl_lic service to start correctly on client machines, the network license server must be running and reachable over the network. If not, then after the network license server is running and reachable, you will need to select "ampl_lic_service" in the "Services and Applications" window and click "start" or "restart".)

On some older versions of MS Windows, such as XP and Vista, it is simpler to install the ampl_lic service by invoking

`alic_service install`

once. (Under Vista, it is necessary to do so while running as the administrator. By right-clicking to start a Command Prompt or sw window, you can select "Run as administrator". Then you can invoke "alic_service install" from the resulting window.) After the alic_service program has installed ampl_lic as a service, alic_service can also remove this service and start or stop it. Invoke "`alic_service -?`" or "`alic_service --help`" to see a summary of such other possibilities. On some MS Windows systems, after installation via alic_service, if relevant network services are not yet running when ampl_lic_service is started after a reboot, ampl_lic will not be able to start, and it may be necessary to invoke

`alic_service stop`
`alic_service start`

to get ampl_lic to start. No matter how you install the ampl_lic service, you can always see whether it is running by invoking

`ampl_lic status`

or

`alic_service status`

As an alternative to ampl_lic_service that is sometimes useful for debugging, licensed programs look for `alic_run.exe` in the same folder as the license file `ampl.lic`; if found, they use it to start `ampl_lic`. `Alic_run` is a Win32 GUI program, which allows the window running the licensed program to be closed while `alic_run` and `ampl_lic` are still running. You can have `alic_run.exe` start `ampl_lic.exe` when the system boots. Do so by putting a copy of `alic_run.exe` into the system Startup folder, which on most systems is

C:\Documents and Settings\Owner\Start Menu\Programs\Startup

`Alic_run` starts up minimized. If you select and close the`alic_run` window, `alic_run` will issue an

`ampl_lic stop`

command before exiting. This will cause the license manager to stop. An alternative to using `alic_run` to start `ampl_lic` is to use an "`sw`" invocation of the form

`sw "c:\full\path\to\ampl_lic"`

such as

`sw "C:\Documents and Settings\Owner\ampl_lic"`

Then you can dismiss the "sw" window without causing the license manager to stop. It can still be stopped with an explicit

`ampl_lic stop`

invocation, but normally there should be no need for such an invocation.

On some Windows systems, such as Windows 7, it is also possible to install ampl_lic as a service, but the procedure is somewhat more cumbersome.

When providing `ampl_lic.exe` for MS Windows, we include a copy of "sw", which is also available for download from the AMPL web site: see

`http://www.ampl.com/DOWNLOADS/details.html#Scrolling`

On the system hosting the network license manager and on all systems to which licenses can float, it is generally convenient to put another copy of `ampl_lic.exe` and a simplified `ampl.lic` file containing only a

MGR_IP = ...

line (giving the IP address of the system hosting the network license manager) into some convenient directory on your regular search $PATH. (Under MS Windows, candidates generally include C:\WINDOWS and C:\WINDOWS\System32 .) Then you can make auxiliary `ampl_lic` invocations from anywhere on these systems. The ... is preferably a specific numerical IP address, but a quoted "hostname" should also work.

On Linux and Unix systems, unless invoked with --nofork, `ampl_lic` forks and makes itself immune to SIGHUP, SIGINT, and SIGQUIT, so once started it should quietly continue operating.

The time drift between client systems and the network license server must be less than 24 hours for the client license managers to start.

Adding a line of the form

`LOGFILE = logfilename`

or

`LOGFILE = "logfilename"`

to `ampl.lic` will cause `ampl_lic` to write some lines to the indicated file. Unless a `VERBOSE = ...` line appears in `ampl.lic`, only start-up, disaster, and shut-down messages will appear. When VERBOSE so specifies (1 for local processes or 5 for local processes and their users, + 2 for network licenses -- only relevant to the network manager), the starting and stopping of licensed processes and changes of license state are also reported in the log file.

The setting

`LOGFILE = -`

causes logging to the standard output (Linux or Unix) or to the `alic_run` window (MS Windows when `alic_run.exe` is used).

It is possible to fiddle with the VERBOSE and LOGFILE settings or even update the license string in `ampl.lic` and then to cause the adjusted settings to take effect by invoking

`ampl_lic restart`

which has an effect similar to "stop" and a new invocation, except that the port does not have to be rebound (which can take several minutes on some systems).

There is a facility for checking out licenses:

`ampl_lic checkout ampl minos 2`

would check out a license for AMPL and two licenses for minos (assuming for sake of illustration that minos is licensed per-process rather than per-machine). This could be useful for remote demos on laptops. The licenses are retained until a corresponding

`ampl_lic return ampl minos 2`

is executed. After the above checkout, if the return line were changed to

`ampl_lic return ampl minos`

only one minos license would be returned; the other would be retained until a subsequent "`ampl_lic return minos`". Licenses are not actually returned until all processes using them have ended.

When returning a checked-out license, a machine must appear to have the same hostname it had when it checked the license out. Some macOS systems come configured to permit remote updates of the hostname, but you can adjust the machine so such updates do not happen. On some recent versions of MacOSX, you can arrange to keep the hostname fixed by selecting

`Apple|System Preferences|Sharing|Computer Name`

clicking "Edit", unselecting "Use dynamic global hostname", and entering the desired Local Hostname. An alternative is to invoke

`scutil --set HostName ...`

as root in a Terminal window, with "..." replaced by the desired hostname.

The license managers periodically update a "state" file and always update it (or remove it if it would be empty) when shutting down. To avoid beating on the file system, they do not immediately update their state files when a licensed process starts or stops. By default, the state file appears in the same directory as ampl.lic and has a name that involves the machine's hostname, e.g., scherzo.ampl_state. It's also possible to explicitly specify the name of the state file with a line of the form

`STATEFILE = "..."`

in `ampl.lic`. (There is also a lock file written in the directory where the license manager appears. This directory need not be on $PATH, and it can be on a cross-mounted file system such that all clients use the same directory -- provided the clients have distinct hostnames.)

Licenses can be retained for a little while before they are returned, which might be useful with scripts that do frequent invocations, as it would reduce the network traffic of conversations between the local and network license managers. A line of the form

`LIC_HOLD = nnn`

(where `nnn` is an integer) would cause a delay of nnn seconds before the license is returned. That way, the license is immediately available if needed again within nnn seconds. The default nnn is 0: no such hold.

When a license is in use, the local manager checks periodically whether the programs that requested the license are still running. By default this happens every 10 minutes, but you can specify a different interval by adding a line of the form

`PROC_CHK = nnn`

to `ampl.lic`. In this line, `nnn` is the number of seconds to wait before checking again. Values of `nnn` less than 20 are treated as 20. (For ampl_lic versions less than 20061202, values less than 40 are treated as 40. Invoke "`ampllic -v`" to see the version.)

In `ampl.lic`, lines that start with `#` are comments (as are empty lines). The same `ampl.lic` file can be used everywhere -- both for the network manager and for the local managers. It's a tiny bit cleaner and more efficient if the `ampl.lic` files for the local managers omit the license string for the network manager, but one can use the same file everywhere.

Other useful invocations include

`ampl_lic netstatus`

which requests a summary of the licenses in use on the whole network, and

`ampl_lic status`

which requests a report of the licensed processes currently running on the local system and of licenses the local system holds for other reasons, such as "ampl_lic checkout" or failure to communicate with the network license manager to return licenses. Before producing its summary, "ampl_lic status" tries to return any licenses held due to LIC_HOLD. If the local license manager is not running, "ampl_lic status" complains, so invoking "ampl_lis status" is a way to check whether the local manager is running. On the other hand, "ampl_lic netstatus" talks directly with the network license manager and works whether or not the local manager is running.

The local license manager may hold licenses because it cannot communicate with the network license manager to return them, perhaps because the network license manager has been stopped or because the network has gone down. In this case, the local manager tries periodically to reestablish contact with the network license manager. The period between tries starts at 15 seconds and increases by 15 second increments up to 15 minutes. If you know that the network manager has just become available again, invoking

`ampl_lic status`

should cause the local manager to return licenses immediately.

If you kill a licensed process or the process faults, the license manager may still think the process is running. Invoking

`ampl_lic status`

will cause the manager to check which processes are still running and to return any licenses that are no longer in use.

In the past, when confusion arose between the local and network license managers, invoking

`ampl_lic restart`

on the local manager (or first on the network manager, then on local managers) would sometimes correct the problem. Some bugs that this exercise circumvented have now been fixed, but if you notice any bad behavior by the local or network license manager, (a) please report it to David M. Gay (dmg at ampl dot com), ideally in enough detail that there is some hope of reproducing the behavior, and (b) try the "ampl_lic restart" exercise to see whether it corrects the trouble.

A license for the floating-license manager comes with one or more ranges of IP addresses builtin over which licenses can float. Starting with version 20110930 of ampl_lic, you can see these ranges by invoking

`ampl_lic ipranges`

or

`ampl_lic ranges`

The latter may use "/mask" notation in which mask is a decimal integer specifying the number of initial bits in a range that are fixed; all the remaining bits can vary. You can replace the builtin ranges by inserting a line of the form

`IPRANGE = range_pat [ range_pat ... ]`

to the `ampl.netlic` file (before the encoded license, e.g., after the "MGR_IP =" line) and can augment the ranges by adding lines of the form

`ADDRANGE = range_pat [ range_pat ... ]`

to the `ampl.netlic` file (following the "IPRANGE =" line, if given). For conventional IPv4 addresses, each range_pat has the form

range_list1.range_list2.range_list3.range_list4

i.e., four range_lists separated by periods, in which each range_list is a comma-separated list of single decimal integers d with 0 ≤ d ≤ 255 and individual ranges of the form m-n, where m and n are decimal integers with 0 ≤ m ≤ n ≤ 255. If m = 0, m can be omitted, and if n = 255, n can be omitted. The last range may be followed by a "/mask" (explained above). For example,

`192.168.1.0-255
192.168.1.-255
192.168.1.0-
192.168.1.-
192.168.1.0/24`

are all treated alike. No spaces may appear in a range_pat, but range_pats are separated by one or more spaces. Each range_pat is a Cartesian product that stands for any IP address w.x.y.z with w in range_list1, x in range_list2, y in range_list3, and z in range_list4.

For IPv6 addresses, each range_pat involves up to 8 range_lists involving up to four hexadecimal digits, with range_lists separated by colons rather than periods. When two or more ranges would just be 0, they may be replaced by a pair of colons. At most one such pair may appear, and if none appears, there must be 8 range_lists. For example,

`fdd8:ed91:f4fe:c1a4:0-ffff:0-ffff:0-ffff:0-ffff
fdd8:ed91:f4fe:c1a4:-:-:-:-
fdd8:ed91:f4fe:c1a4::/64`

all have the same meaning. The output from

`ampl_lic ipranges`

or

`ampl_lic ranges`

reflects the IPRANGE and ADDRANGE lines after they are combined where possible and sorted. The network license manager is allowed to use licenses even if its IP address is not in the specified set of ranges over which licenses can float.

For possible help in diagnosing trouble, if ampl_lic is running locally, the output from

`ampl_lic licshow`

reports the full pathname by which ampl_lic was invoked and the full pathname and contents of the `ampl.netlic` or `ampl.lic` it read.