.TH INIT .SH NAME init, svc, halt, shutdown, reboot, reset \- run and control services .SH SYNOPSIS .B init [ .B -d .I svcdir ] [ .B -l .I logdir ] [ .B -m .I mtpt ] [ .B -s .I srvname ] .PP .B svc [ .I cmd [ .I name ... ]] .PP .B halt .br .B shutdown .br .B reboot .br .B reset .SH DESCRIPTION .I Init runs the services described in .BR /lib/svc . It is not tied to booting; see .B AS SYSINIT below. .PP To interact with services, mount the filesystem .I init serves: .PP .EX mount /srv/svc /mnt/svcs .EE .PP This is optional. Services run whether or not anyone ever mounts it, and if .I init cannot post the filesystem it says so and carries on supervising. The control plane is for people, not for the machine. .PP Options are: .TP .BI -d " svcdir" Read service definitions from .I svcdir instead of .BR /lib/svc . .TP .BI -l " logdir" Write service output to .I logdir instead of .BR /log . .TP .BI -m " mtpt" Mount at .I mtpt instead of .BR /mnt/svcs . .TP .BI -s " srvname" Post at .BI /srv/ srvname instead of .BR /srv/svc . .PP Every path is an option because .I init must be runnable as an ordinary process for testing. See .B TESTING below. .SH CONFIGURATION IS FILES .I Init never writes .BR /lib/svc . Everything about how a service is configured, including whether it starts at boot, is in its file and is changed by editing that file. The filesystem described below accepts commands about what is running now; it does not accept configuration, and there is no exception to this. .PP The consequence worth knowing before it surprises you: .B stop does not survive a reboot. To stop a service from starting at boot, set .B enable=no in its file. To act on an edit without rebooting, use .BR reload . .SH COMMANDS These are small programs that open a file and write a word to it. Anything they do can be done by hand; see .B THE SERVICE FILESYSTEM below. .TP .B svc With no arguments, print every service, its state, and why it is in that state, in aligned columns. .TP .BI svc " cmd name ..." .I Cmd is .BR start , .BR stop , .BR restart , .BR status , or .BR log . .B Svc log prints what the service has written and then keeps printing as it writes more, until interrupted. .TP .B halt Stop all services, halt the file server, and power off. .B Shutdown is another name for it. .TP .B reboot As .BR halt , but restart the kernel. .TP .B reset Stop all services and start them again. The kernel keeps running and the file server is not halted. .PP To make this machine an authentication server, put .B enable=yes in the .B keyfs and .B authsrv files and then: .PP .EX svc reload svc start keyfs authsrv .EE .SH THE SERVICE FILESYSTEM .EX /mnt/svcs/ ctl control everything status state of every service / ctl control one service status state of one service args command line env environment ns namespace in effect user identity it runs as log output pid .EE .PP Every file except the two .B ctl files is read-only. Configuration is changed by editing .BR /lib/svc , never here. .PP Which file you write to says how far a command reaches. The two .B ctl files accept: .PP .EX /mnt/svcs/ctl /mnt/svcs//ctl start start start stop stop stop restart restart restart note - note reload reload - reexec reexec - halt reboot reset yes - .EE .PP .B Start and .B stop affect only what is running now. .B Note posts a note to the service's process. .B Reload re-reads .BR /lib/svc . .B Reexec replaces .I init with a new .I init binary without stopping services or rebooting. .PP Reading a .B ctl file lists the commands it accepts, so you never have to guess or read source: .PP .EX % cat /mnt/svcs/dns/ctl start stop restart note post a note to the process .EE .PP A write that is not understood fails and names the alternatives: .PP .EX % echo frobnicate >/mnt/svcs/ctl echo: write error: unknown command "frobnicate"; try halt reboot reset start stop restart reload reexec .EE .PP .B Status is in .I ndb format rather than columns, so that fields can be added without breaking anything that reads it, and so that an exit message containing blanks needs no special case: .PP .EX % cat /mnt/svcs/status svc=dns state=running pid=231 enable=yes svc=authsrv state=failed restarts=3 exit='cannot open /adm/keys' svc=listen state=waiting needs=cs svc=ipconf state=done .EE .PP The states are: .TF starting .TP .B stopped Not running, and not trying to be. .TP .B waiting Wants to run, but something in its .B needs has not come up yet. The .B needs attribute in .B status says which. .TP .B starting Started, but not yet up according to its .B ready attribute. .TP .B running Up. .TP .B done A .B ready=exit service that finished successfully. It is not running and will not be started again. .TP .B failed Gave up. The .B exit attribute says why. .PP .B Pid is empty for a service that has no process of its own: a .B ready=srv: service whose process has exited by design, or one that has finished or not started. .PP Permissions are ordinary file permissions, checked by .I init against the identity of whoever attached, so the same rules apply to a local write and to a remote mount. By default the global .B ctl is writable only by the host owner, and a service's own .B ctl is writable by the host owner and by the user the service runs as. Note that if .B /srv/svc is exported, anyone who can mount it can halt the machine. .SH SERVICE FILES Each file in .B /lib/svc describes one service, in .I ndb format. .PP .EX svc=dns exec=/bin/ndb/dns args=-r needs=cs ready=srv:dns restart=always enable=yes .EE .PP The attributes are: .TF restart .TP .B svc The name. Must match the file name. .TP .B exec Program to run. Required unless .B adopt=yes is set. .TP .B args An argument. May be repeated, and repeated attributes are passed in the order they appear in the file. .TP .B env A .IB name = value pair for the environment. May be repeated. .TP .B needs Another service that must come up first. May be repeated. A dependency is satisfied when it reaches .B running or .BR done . This is ordering only: if a dependency later fails or is restarted, nothing happens to the services that named it. Cycles are reported by .BR reload . .TP .B ready How to tell the service has come up, and for one form, how to tell it is still up. See .B KINDS OF SERVICE below. .TP .B restart .BR never , .B onfail (the default: restart only on a non-empty exit status), or .BR always . What is watched depends on .BR ready , so see .B KINDS OF SERVICE before setting this. .TP .B stop How to stop it, when a .B hangup note will not do. One of: .RS .TP .BI note: string Post .I string as a note. The default is .BR note:hangup . .TP .IB write: file : word Write .I word to .IR file . This is how a file server that shuts down on a command to its .B /srv file says so, for example .BR write:/srv/hjfs.cmd:halt . .TP .BI exec: cmd Run .IR cmd . .RE .TP .B adopt .B yes for a service .I init did not start and cannot start: it has no .BR exec , .I init is not its parent, and it can only be stopped. The root file server is the case this exists for. An adopted service needs a .B ready attribute so that .I init can tell whether it is there, and a .B stop attribute so that .I init can shut it down. .TP .B ns A namespace file, in the format of .IR namespace . .TP .B user The identity to run as. .TP .B enable .B yes to start at boot. Only a person writes this; .I init never does. .PP An attribute that is not in this list is an error. Nothing here is a hint: .B exce=/bin/ndb/dns is valid ndb and means nothing, so ignoring unknown attributes would let a typo do nothing quietly forever. .PP There is nothing else to set. The times involved are fixed: a service gets 30 seconds to become ready, 5 seconds to stop before it is killed, and 1 second between restarts; a service that restarts more than 5 times in 60 seconds is marked .BR failed . These are constants until something demonstrates they need to be otherwise. .PP .B Reload applies every file that parses and leaves the rest alone, so one bad file never costs you the machine. The write fails with a summary, and each service that could not be loaded says why in its own .BR status : .PP .EX % echo reload >/mnt/svcs/ctl echo: write error: 2 of 14 service files rejected; see status % grep 'state=failed' /mnt/svcs/status svc=dns state=failed exit='/lib/svc/dns:4: unknown attribute "exce"' .EE .SH KINDS OF SERVICE Not everything stays in the foreground, and .I init does not guess. The .B ready attribute says how to tell a service came up, and in one case what to watch afterwards. .TF srv:name .TP .B exec It stays in the foreground and is up as soon as it is started. Its process is watched, and .B restart applies to that process exiting. This is the default. .TP .BI srv: name It is up once .BI /srv/ name exists. Use this for a service that posts to .B /srv and lets the process you started exit, which many Plan 9 file servers do on purpose. For these the .B /srv file is watched and the process is not, so the process exiting is normal and never causes a restart; .B restart applies to the .B /srv file going away. .TP .BI dial: addr It is up once a dial of .I addr succeeds. This is a readiness test only: the process is still what is watched afterwards, exactly as for .BR exec , and .I init does not keep dialling. .TP .B exit It runs once and finishes; it is not a daemon. Use this for setup that has to happen before something else starts. It reaches .B done rather than .BR running , it satisfies .B needs by doing so, and it is never restarted \- a .B restart attribute on it is an error rather than something quietly ignored. .SH NAMESPACE AND USER Each service runs in its own namespace group. If it has an .B ns attribute that namespace is built from the named file; otherwise it inherits the namespace .I init is using. This is what lets two services on one machine hold entirely different views of the filesystem \- a different .BR /net , a different .BR /srv , a different .B /mnt/factotum and so different keys and a different identity. .PP Because a service has its own namespace, a service that runs .I bind changes nothing for anyone else. Services use namespaces; they do not build the shared one. The namespace everything starts from is built by .I init before any service runs. .PP A service with a .B user attribute is run under that identity using the capability device, since Plan 9 has no setuid. This requires .I init to be running as the host owner; an .I init that is not cannot honour .B user and fails any service that asks for one, rather than silently running it as the wrong identity. .SH STARTING AND STOPPING Services marked .B enable=yes are started in dependency order, each waiting for the ones it .B needs to reach .B running or .BR done . .PP They are stopped in the reverse of that order. Each is stopped the way its .B stop attribute says, or by a .B hangup note; if it has not gone after 5 seconds it is killed. A stuck service never holds up the rest. .SH AS SYSINIT Nothing above depends on how .I init was started. An instance can be run by anyone, over any directory of services, in its own namespace \- to hold up the parts of an application, say, and redeploy them by discarding the namespace and starting again. .PP When it is the program that brings a machine up, it does four more things. .PP It builds the base namespace that everything else inherits. Services run in their own namespace groups and so cannot do this for one another. .PP It offers a shell on the console when the machine cannot be reached any other way. .PP It stops the adopted root file server last, after everything that might be using it. .PP It powers the machine off, or reboots it, which is what .B halt and .B reboot finally do. .SH LOGGING Everything a service writes to standard output or standard error is appended to .BI /log/ name\fR. .B /mnt/svcs/\fIname\fB/log is a view of that file; reading it at the end blocks until there is more, so it can be followed. .PP Nothing rotates these files. That is deliberate: appending is a few lines and rotating is a program, and it is not going in init. .PP Before there is a writable filesystem, and again once shutdown has started, there is nowhere to append to and messages go to the console instead. .SH TESTING Supervising services does not require being the program that boots the machine, so .I init can be run as an ordinary program against a directory of test services: .PP .EX init -d /tmp/svc.test -l /tmp/log.test -s svc.test -m /mnt/svcs.test .EE .PP Give .B -l as well as the rest, or the test instance appends to the real .BR /log . .PP What such an instance cannot exercise is the base namespace, the rescue console, halting the adopted root file server, and any service with a .B user attribute, since changing identity needs the host owner. .SH FILES .TF /mnt/svcs .TP .B /lib/svc service definitions .TP .B /mnt/svcs the service filesystem .TP .B /srv/svc where it is posted .TP .B /log service output .SH SOURCE .B /sys/src/cmd/init.c .br .B /sys/src/cmd/svc .SH SEE ALSO .IR ndb , .IR namespace , .IR cap , .IR srv , .IR rc .SH BUGS A service written in .I rc must .I exec its final program rather than starting it with .BR & . Otherwise .I init supervises the shell, the shell exits immediately, and the program it started is left running with nothing watching it. .PP There is no notification when a file changes, so a service watched by its .B /srv file is not noticed to have died until something looks. The entry itself is removed when the server dies, with or without an active mount held on it, so looking is enough; only the delay is at issue. .PP Nothing detects a service that is running but not answering. A wedged server keeps both its process and its .B /srv entry and so reads as .B running under every .B ready form. Only a real 9P transaction would show otherwise, and .I init does not make one. .PP .B Reexec keeps services running but not mounts: anyone who already has .B /srv/svc mounted holds fids that cannot survive the exec, and has to mount it again. .PP On a machine that cannot be powered off, .B halt stops everything, says so, and leaves the machine running. .PP Nothing restarts .I init if it dies. .PP There is no resource control of any kind.