Seth Woolley's Man Viewer

provide(8) - initctl - utility to control simpleinit(8) - man 8 provide

([section] manual, -k keyword, -K [section] search, -f whatis)
man plain no title

INITCTL(8)           Linux System Admininstrator's Manual           INITCTL(8)



NAME
       initctl - utility to control simpleinit(8)

SYNOPSIS
       initctl [ -c | -d | -n | -p | -r ] [ -f ] [ -u ] service
       need [ -f ] [ -r ] service
       provide service
       display-services
       initctl service
       initctl -c service


OVERVIEW
       Simpleinit(8) offers a service and dependency management scheme to help
       improve the robustness, scalability  and  readability  of  system  boot
       scripts.  It is now possible to write(1,2) a modularised set(7,n,1 builtins) of boot scripts
       without the complex and fragile numbered symlink  scheme  used  by  the
       SysV boot concept.  Simpleinit(8) uses combined start/stop scripts that
       determine their function by the 1st argument passed to  them.  Combined
       start/stop  scripts  from  SysV  installations  can  be  reused  almost
       unchanged most of the time.  Calling those scripts in(1,8) the proper  order
       is  handled automatically.  Scripts simply declare, using need(8), what
       must run before them and the need -r function will stop them in(1,8) reverse
       order.

       Note: For the rest of this document, a script started with the argument
       'start' will be referred to as a 'start script' and when  started  with
       the  argument  'stop'  it  will be referred to as a 'stop script', even
       though both functions are combined in(1,8) a single script.


DESCRIPTION for need
       When invoked as need or with  the  -n  switch(1,n),  initctl(8)  tells  sim-
       pleinit(8)  to  start  a  service. Services come in(1,8) 2 flavours. Primary
       services are executable programs, usually scripts, that init will  call
       with  the  argument  'start'.  Secondary services are those linked to a
       primary service with provide(8) (see below).  If the requested  service
       is  already available, need will return immediately without starting it
       again.

       If the requested service is  not  yet  available  (i.e.  it  was  never
       started  or failed the last time(1,2,n)), need will look(1,8,3 Search::Dict) for a primary service
       of the specified name. If a full pathname is  not  specified,  it  will
       look(1,8,3 Search::Dict)  in(1,8)  the  directories specified via INIT_PATH in(1,8) /etc/inittab (see
       simpleinit(8)) and run it with the 'start'  argument.  It  will  return
       when  the  respective program has terminated.  It is also possible that
       the requested service is not  yet  available  but  is  currently  being
       started  (one  or more parallel processes may be trying to provide it).
       In that case need(8) will wait until the service is either available or
       all programs trying to provide the service have failed.

       The  service  to start may also be the name of a directory instead of a
       script.  In this case, the fileprefix/bootprog program as specified  in(1,8)
       inittab(5)  will  be  executed  with a 1st argument 'start-dir' and the
       full path to the  directory  as  2nd  argument.  The  boot  program  is
       expected  to  behave  as  if(3,n)  it was a start script in(1,8) this case, which
       means it must exit(3,n,1 builtins) with a proper exit(3,n,1 builtins) code as  described  in(1,8)  the  BOOT
       SCRIPT GUIDELINES further below.


DESCRIPTION for need -r
       The  -r option is used to tell simpleinit(8) to "roll back" (stop) ser-
       vices up to (but not  including)  service  by  running  the  respective
       scripts with the 'stop' parameter.  If a service refers to a directory,
       rather than an actual script (see DESCRIPTION for need above)  filepre-
       fix/bootprog  will  be  called  with 'stop-dir' as 1st argument and the
       full path to the directory as  2nd  argument.  The  boot  program  must
       behave like a stop script in(1,8) this case, which means it must exit(3,n,1 builtins) with a
       proper exit(3,n,1 builtins) code as described in(1,8) the  BOOT  SCRIPT  GUIDELINES  further
       below.

       If  service  is not specified, all services are stopped.  The -r option
       thus allows the system to be  partially  or  wholly  shut  down  in(1,8)  an
       orderly fashion. The shutdown(2,8)(8) program automatically calls initctl -r
       -f as part of its operation.

       If a rollback is already in(1,8) progress  when  another  one  is  requested
       (e.g.  if(3,n)  a stop script uses need -r), the new request will be ignored
       if(3,n) it requests rolling back fewer services. If it requests rolling back
       more  services,  the  rollback  will be extended. It is not possible to
       activate or deactivate the -f switch(1,n) (see below) setting of a  rollback
       in(1,8) progress.

       The  -f option forces the rollback to succeed. All stop scripts will be
       assumed to successfully terminate regardless of their  exit(3,n,1 builtins)  codes.   A
       watchdog(5,8) will also be set(7,n,1 builtins) for every stop script that will kill(1,2,1 builtins) (SIGTERM
       followed by SIGKILL) the stop script if(3,n) it does not terminate within  5
       minutes  after  being  started. This option is intended only for use by
       shutdown(2,8)(8) to ensure that the system will never hang indefinitely dur-
       ing shut down even if(3,n) services are messed up badly.


DESCRIPTION for provide
       When invoked as provide, initctl(8) tells simpleinit(8) that the parent
       (calling) process will be providing service.  If  the  calling  process
       exits  successfully  (status  0) the service is deemed to be available.
       Only one instance of service may be  started,  so  alternate  providers
       will block and may fail.

       Using  provide  it is possible to have multiple potential providers for
       the same (generic) service (e.g. sendmail(1,8) and qmail both provide a  mta
       service),  where  only  one  actually provides the service. This may be
       used by service startup scripts which check for configuration files.


DESCRIPTION for display-services
       When invoked as display-services or with the -d switch(1,n), initctl(8) will
       write(1,2)  the  list of currently available services, primary services just
       being started and the list of failed services to the  standard  output.
       When invoked as initctl without a switch(1,n) it will test for the status of
       service (see EXIT CODE below)


DESCRIPTION for initctl -c
       initctl -c service will  clear(1,3x,3x clrtobot)  service  from  simpleinit(8)'s  service
       accounting  lists without actually stopping the service. It affects the
       services that are available as well as those that have failed. It  does
       not  affect  services currently being started.  If a primary service is
       cleared then all secondary services linked to it will be removed,  too.
       This function should be used with care. Once a service has been removed
       from simpleinit(8)'s lists, it is treated as if(3,n) it had never been  run.
       Only use this function if(3,n) you know what you're doing!


USER SPACE EXECUTION
       The  -u  switch(1,n)  tells initctl(8) that it is to communicate with a sim-
       pleinit(8) run in(1,8) user space instead of the main system init.   If  the
       user   invoking  initctl(8)  does  not  have  permission  to  write(1,2)  to
       /dev/initctl or the environment variable  USERSPACE_INIT  exists,  user
       space  mode will be set(7,n,1 builtins) automatically.  The -u switch(1,n) is only necessary
       if(3,n) a privileged user wants  to  communicate  with  a  user  space  sim-
       pleinit(8).  Note  that in(1,8) this case, indirect calls to initctl(8) made
       in(1,8) scripts started via need -u will inherit the -u  switch.   For  user
       space communication initctl(8) will use the $INIT_ROOT/dev/initctl FIFO
       rather than /dev/initctl.  If the INIT_ROOT environment variable is not
       set(7,n,1 builtins), it will default to the current working directory.

       Even  if(3,n) the INIT_ROOT environment variable is set(7,n,1 builtins) correctly and the -u
       switch(1,n) is supplied, communication may not be possible.  If the user who
       started the user space init does not have permission to send(2,n) signals to
       the user running initctl(8), or the other way around,  initctl(8)  will
       wait  forever for an answer and has to be terminated manually. The same
       problem occurs if(3,n) one of the 2 does not have write(1,2) permission to  files
       created  by  the  other one. This means that even with the -u switch(1,n), a
       user can usually only communicate with a user space  init  launched  by
       himself.


EXIT CODE
       The exit(3,n,1 builtins) code from need is 0 if(3,n) the service was successfully started, 1
       if(3,n) the service failed badly, and 2 if(3,n) the service is unavailable  (i.e.
       disabled  in(1,8)  configuration  files).  These exit(3,n,1 builtins) codes reflect the exit(3,n,1 builtins)
       codes from the service startup  scripts  (see  BOOT  SCRIPT  GUIDELINES
       below).   Exit  code  3  will be returned if(3,n) a rollback is currently in(1,8)
       progress, unless the service is available.  If a script calls need  for
       itself, 0 will be returned.

       The exit(3,n,1 builtins) code from need -r is 0 if(3,n) the requested services were success-
       fully stopped, 1 if(3,n) they could not (all) be stopped, and 2 if(3,n) the  ser-
       vice  to  roll back to was not available to start with. Note that if(3,n) no
       service is specified (i.e rolling back everything) and no services  are
       available,  the  exit(3,n,1 builtins)  code  will  be  0,  not  2.  Exit code 3 will be
       returned if(3,n) a rollback is already in(1,8) progress.

       The exit(3,n,1 builtins) code from provide is 0 if(3,n) the service may be provided, 1 if(3,n) it
       may not. Exit code 2 will be returned if(3,n) the process calling provide is
       not a child of init (i.e. not  started  at  boot-up  or  via  a  manual
       need(8)) or an error(8,n) has occurred during the call.  Exit code 3 will be
       returned if(3,n) a roll back is currently in(1,8) progress.   provide  may  block
       waiting till another provider trying to initialise the service has fin-
       ished.

       The exit(3,n,1 builtins) code from initctl -c is 0 if(3,n) the service was removed from  the
       list  of available services, 1 if(3,n) the service was removed from the list
       of unavailable services, and 2 if(3,n) the service was not found  in(1,8)  either
       of these lists.

       The  exit(3,n,1 builtins)  code  from initctl (without switches) is 0 if(3,n) the service is
       available, 1 if(3,n) the service failed badly,  and  2  if(3,n)  the  service  is
       unavailable. These exit(3,n,1 builtins) codes are the same as would be returned by need
       service.  Exit code 3 will be returned if(3,n) information  about  the  ser-
       vice's  status  is  not  available. This is the case if(3,n) it is currently
       starting (i.e. the start script has not  terminated,  yet),  has  never
       been  run  at  all, or if(3,n) the service has been stopped or cleared. Note
       that during a rollback in(1,8)  progress  a  service's  status  will  remain
       available  until  the service's stop script has actually terminated. So
       if(3,n) a service's stop script tests the status of its own service, 0  will
       be  returned  if(3,n)  the  service was started successfully (the usual case
       unless the stop script was executed manually by the user without  using
       need first).

       The  exit(3,n,1 builtins) code for display-services is 0 unless communication with init
       fails for some reason.


BOOT SCRIPT GUIDELINES
       The scripts used with simpleinit(8)/initctl(8) have to  follow  certain
       rules to ensure proper service management. The requirements are as fol-
       lows:

       Every script must understand 'start' and 'stop' passed to it as the 1st
       argument.  If  the  argument is not applicable (e.g. for a service that
       doesn't require stopping) it must be handled gracefully.

       Start scripts may only return the exit(3,n,1 builtins) codes 0, 1 and 2.   Their  mean-
       ings are as follows:


       0      The service was successfully started and is now available.


       1      An  error(8,n) has occurred when starting the service. The service is
              not made available.


       2      The service may be able to start successfully but is not config-
              ured  to  be started (e.g. disabled in(1,8) a config(1,5) file(1,n)).  The ser-
              vice is not made available.


       The use of exit(3,n,1 builtins) code 2 is optional. Exit code 1 may be used instead. It
       is  important to note that in(1,8) both cases the service is not made avail-
       able. Exit code 2 does not mean that the script may  or  may  not  have
       provided the service. Every service must either be started successfully
       or not started all. Scripts that return a non-zero exit(3,n,1 builtins)  code  must  be
       prepared  to  be  called again. need(8) only ensures that services that
       have started successfully will not be started again.

       Stop scripts may only return the exit(3,n,1 builtins) codes 0 and  1.   Their  meanings
       are as follows:


       0      The  service  was  stopped  successfully  (or did not need to be
              stopped) and is not available anymore.


       1      An error(8,n) has occurred stopping the service. The service is still
              available.


       If  one  of the stop scripts returns a non-zero exit(3,n,1 builtins) code, rolling back
       will be stopped and the service whose stop script failed will  be  con-
       sidered  still  available.   Make  sure  that  your stop scripts do not
       return a non-zero exit(3,n,1 builtins) code if(3,n) the service is no longer available!

       A script providing a secondary service must check the  exit(3,n,1 builtins)  code  from
       provide to see if(3,n) it is allowed to provide the service, before attempt-
       ing to do so. If the service may not be  provided,  it  is  recommended
       that the script terminate with exit(3,n,1 builtins) code 2 (see start script exit(3,n,1 builtins) codes
       above).  However, a script may try to provide several services.  If  it
       returns  with  exit(3,n,1 builtins) code 0, the script's primary service will be deemed
       available, as will any secondary services for which  the  provide  call
       returned 0.

       When  a  script  provides multiple services, it is recommended (but not
       required) that it lists them in(1,8) alphabetical order to prevent deadlocks
       when parallel execution is used (see DEADLOCKS below).


DEADLOCKS
       It is possible to create a variety of deadlock situations with need and
       provide, especially when executing several start scripts  in(1,8)  parallel.
       Simpleinit(8)  detects  deadlocks  and breaks them by having some needs
       and/or provides return an error(8,n) condition.  The only exception is  when
       a  script uses need on itself. In this case of a minimal deadlock, need
       will be successful. This helps when you merge(1,8) several scripts into  one
       and want to preserve the dependency statement.
       Note   that  deadlock  detection  only  works  for  scripts  that  call
       initctl(8) directly, i.e. not via a subshell. So if(3,n) you create a script
       need-service for instance, and only call need via this script, deadlock
       detection is impossible. You should implement need-service as  a  shell
       function instead, to prevent that it is executed in(1,8) a subshell.

       Whenever  a deadlock is detected, simpleinit(8) will write(1,2) the names of
       the conflicting scripts to the console. In most cases the culprit is  a
       circular  dependency like "a provides b, a needs c, c needs b". This is
       a bug in(1,8) your boot scripts. In the above case it would be  required  to
       make  sure  that  an  alternate provider of service b is started before
       service a.

       One deadlock case deserves special discussion. This is a case like  the
       following:

       script 1:
              provide a
              sleep(1,3) 10
              provide b

       script 2:
              provide b
              sleep(1,3) 10
              provide a

       When  executing these scripts in(1,8) parallel, a race condition exists that
       can end in(1,8) a deadlock (script 1 gets(3,n) permission to provide a and script
       2  gets(3,n)  permission  to  provide b, both block on the 2nd provide while
       waiting for the other script to finish). Again this is a  bug  in(1,8)  your
       boot scripts which simpleinit(8) will detect and output.  However, this
       one is different in(1,8) that the race condition is easy  to  avoid  without
       changing the meaning of the scripts. All you have to do is to make sure
       that whenever a script provides multiple services, it does so in(1,8) alpha-
       betical  order.  In the above case script 2 would have to be changed to
       begin with "provide a" rather than "provide b".

       In general it is best to avoid parallel  execution  of  start  scripts.
       Unlike util-linux's version(1,3,5), simpleinit-msb does not have built-in sup-
       port for parallel execution anymore but using your shell's  background-
       ing abilities, you could still cause parallel execution of scripts.


SIGNALS
       initctl(8)  uses SIGUSR1, SIGUSR2, SIGURG and SIGPOLL for communication
       with simpleinit(8). Don't send(2,n) these signals to it (why would you  want
       to, anyway?).


BUGS
       initctl(8)  currently  treats  service and /full/path/service as 2 dis-
       tinct services, even if(3,n) service resolves (via INIT_PATH)  to  the  same
       script.  Different  pathnames  that  refer  to the same script are also
       taken as distinct. If you are not careful  this  can  lead  to  scripts
       being  executed  multiple  times  even  if(3,n)  they're not supposed to be.
       Assuming that the service fsck  is  in(1,8)  filesys/  and  filesys/  is  in(1,8)
       INIT_PATH, a possible error(8,n) would be

              need fsck || exit(3,n,1 builtins) 1
              for service in(1,8) filesys/*; do need $service; done

       To  work  around  this problem you should never use absolute paths with
       initctl(8). Avoiding absolute paths also makes it easier to  move(3x,7,3x curs_move)  your
       boot  scripts  to a different location. In any case you should not rely
       on the above behaviour as it might change in(1,8) future versions.

       When need svc is issued while a script scp attempting to provide svc as
       a secondary service still hasn't finished, the primary service svc will
       never be attempted, even if(3,n) the script scp fails.  This means  that  if(3,n)
       parallel  execution is used and you have a service svc that exists both
       as primary and secondary service, then you always  have  a  race-condi-
       tion.   As  a workaround you should use different names for primary and
       secondary services.
       When running boot scripts in(1,8) sequence (the only way directly  supported
       by this version(1,3,5) of simpleinit), a need svc while a provide svc is still
       pending is an error(8,n) in(1,8) the boot script setup(2,8) (circular dependency,  see
       DEADLOCKS above) so the above issue does not apply to (correct) sequen-
       tial setups.

       need(8) will start a service even if(3,n) the name ends in(1,8) "~". This is  not
       a bug but it is something to keep in(1,8) mind when using loops like
              cd dir
              for service in(1,8) *; do need $service; done
       This loop will also execute backup files that end in(1,8) "~".



FILES
       /dev/initctl        This is the control FIFO, created by simpleinit(8),
                           which initctl(8) writes commands to.

       $INIT_ROOT/dev/init.pid
                           This file(1,n) is used to determine the pid of init when
                           run  in(1,8) user space.  See simpleinit(8) for details.

       /etc/inittab        Settings in(1,8) this file(1,n) control the behaviour of some
                           aspects  of initctl(8). See simpleinit(8) and init-
                           tab(5) for details.

AUTHOR
       Richard Gooch (rgooch@atnf.csiro.au)

       This version(1,3,5) was modified by Matthias Benkmann <m.s.b@gmx.net>. Contact
       me if(3,n) you have any problems with this version.

SEE ALSO
       simpleinit(8), init(8), shutdown(2,8)(8), inittab(5)



                                  8 Sep 2001                        INITCTL(8)

References for this manual (incoming links)