From mboxrd@z Thu Jan 1 00:00:00 1970 From: Mathieu Lirzin Subject: [Shepherd][PATCH 3/4] doc: Move manual to the 'doc' directory. Date: Wed, 27 Jan 2016 21:45:33 +0100 Message-ID: <1453927534-32056-4-git-send-email-mthl@gnu.org> References: <1453927534-32056-1-git-send-email-mthl@gnu.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="------------2.7.0.rc3" Return-path: Received: from eggs.gnu.org ([2001:4830:134:3::10]:39695) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1aOWyw-0008T6-Cv for guix-devel@gnu.org; Wed, 27 Jan 2016 15:46:43 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1aOWyd-0000Sn-JB for guix-devel@gnu.org; Wed, 27 Jan 2016 15:46:26 -0500 In-Reply-To: <1453927534-32056-1-git-send-email-mthl@gnu.org> List-Id: "Development of GNU Guix and the GNU System distribution." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: guix-devel-bounces+gcggd-guix-devel=m.gmane.org@gnu.org Sender: guix-devel-bounces+gcggd-guix-devel=m.gmane.org@gnu.org To: guix-devel@gnu.org This is a multi-part message in MIME format. --------------2.7.0.rc3 Content-Type: text/plain; charset=UTF-8; format=fixed Content-Transfer-Encoding: quoted-printable * doc/shepherd.texi: Moved from the root directory. * doc/fdl-1.3.texi: Likewise. * Makefile.am (info_TEXINFOS): Add a 'doc/' prefix to 'shepherd.texi'. (EXTRA_DIST): Remove 'fdl-1.3.texi'. (doc_shepherd_TEXINFOS): New variable. * .gitignore: Update it. --- .gitignore | 49 +- Makefile.am | 4 +- doc/fdl-1.3.texi | 505 +++++++++++++++++ doc/shepherd.texi | 1593 +++++++++++++++++++++++++++++++++++++++++++++++= ++++++ fdl-1.3.texi | 505 ----------------- shepherd.texi | 1593 -----------------------------------------------= ------ 6 files changed, 2125 insertions(+), 2124 deletions(-) create mode 100644 doc/fdl-1.3.texi create mode 100644 doc/shepherd.texi delete mode 100644 fdl-1.3.texi delete mode 100644 shepherd.texi --------------2.7.0.rc3 Content-Type: text/x-patch; name="0003-doc-Move-manual-to-the-doc-directory.patch" Content-Disposition: inline; filename="0003-doc-Move-manual-to-the-doc-directory.patch" Content-Transfer-Encoding: quoted-printable diff --git a/.gitignore b/.gitignore index 7cb94f2..111817f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,26 +1,29 @@ -/configure -/shepherd.info -/stamp-vti -/version.texi +*.go +*~ +,* +.dirstamp +/*.1 +/*.8 +/INSTALL +/aclocal.m4 +/autom4te.cache +/build-aux/* /config.cache /config.log /config.scm /config.status -/herd -/shepherd +/configure +/doc/shepherd.info +/doc/stamp-vti +/doc/version.texi /examples/Makefile -/autom4te.cache -/build-aux/* -Makefile.in -Makefile -*~ -,* +/halt +/herd /missing -/texinfo.tex -/INSTALL -/aclocal.m4 -*.go /modules/shepherd/config.scm +/modules/shepherd/system.scm +/reboot +/shepherd /shepherd.aux /shepherd.cp /shepherd.cps @@ -28,28 +31,26 @@ Makefile /shepherd.fns /shepherd.ky /shepherd.log +/shepherd.pdf /shepherd.pg /shepherd.toc /shepherd.tp /shepherd.tps /shepherd.vr /shepherd.vrs -/modules/shepherd/system.scm -/halt -/reboot -/shepherd.pdf /test-suite.log /tests/basic.log /tests/basic.trs /tests/misbehaved-client.log /tests/misbehaved-client.trs -/tests/respawn.log -/tests/respawn.trs /tests/no-home.log /tests/no-home.trs +/tests/respawn.log +/tests/respawn.trs /tests/sigint.log /tests/sigint.trs /tests/status-sexp.log /tests/status-sexp.trs -/*.1 -/*.8 +/texinfo.tex +Makefile +Makefile.in diff --git a/Makefile.am b/Makefile.am index 2985a86..52f66d6 100644 --- a/Makefile.am +++ b/Makefile.am @@ -66,7 +66,8 @@ CLEANFILES =3D \ $(bin_SCRIPTS) $(sbin_SCRIPTS) =20 # Documentation. -info_TEXINFOS =3D shepherd.texi +info_TEXINFOS =3D doc/shepherd.texi +doc_shepherd_TEXINFOS =3D doc/fdl-1.3.texi =20 AM_V_HELP2MAN =3D $(AM_V_HELP2MAN_$(V)) AM_V_HELP2MAN_ =3D $(AM_V_HELP2MAN_$(AM_DEFAULT_VERBOSITY)) @@ -98,7 +99,6 @@ dist_man8_MANS =3D halt.8 reboot.8 # Things not automatically included in the distribution. EXTRA_DIST =3D \ ChangeLog-2003 \ - fdl-1.3.texi \ QUESTIONS \ $(templates) \ doc/examples/README \ diff --git a/doc/fdl-1.3.texi b/doc/fdl-1.3.texi new file mode 100644 index 0000000..cb71f05 --- /dev/null +++ b/doc/fdl-1.3.texi @@ -0,0 +1,505 @@ +@c The GNU Free Documentation License. +@center Version 1.3, 3 November 2008 + +@c This file is intended to be included within another document, +@c hence no sectioning command or @node. + +@display +Copyright @copyright{} 2000, 2001, 2002, 2007, 2008 Free Software Founda= tion, Inc. +@uref{http://fsf.org/} + +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. +@end display + +@enumerate 0 +@item +PREAMBLE + +The purpose of this License is to make a manual, textbook, or other +functional and useful document @dfn{free} in the sense of freedom: to +assure everyone the effective freedom to copy and redistribute it, +with or without modifying it, either commercially or noncommercially. +Secondarily, this License preserves for the author and publisher a way +to get credit for their work, while not being considered responsible +for modifications made by others. + +This License is a kind of ``copyleft'', which means that derivative +works of the document must themselves be free in the same sense. It +complements the GNU General Public License, which is a copyleft +license designed for free software. + +We have designed this License in order to use it for manuals for free +software, because free software needs free documentation: a free +program should come with manuals providing the same freedoms that the +software does. But this License is not limited to software manuals; +it can be used for any textual work, regardless of subject matter or +whether it is published as a printed book. We recommend this License +principally for works whose purpose is instruction or reference. + +@item +APPLICABILITY AND DEFINITIONS + +This License applies to any manual or other work, in any medium, that +contains a notice placed by the copyright holder saying it can be +distributed under the terms of this License. Such a notice grants a +world-wide, royalty-free license, unlimited in duration, to use that +work under the conditions stated herein. The ``Document'', below, +refers to any such manual or work. Any member of the public is a +licensee, and is addressed as ``you''. You accept the license if you +copy, modify or distribute the work in a way requiring permission +under copyright law. + +A ``Modified Version'' of the Document means any work containing the +Document or a portion of it, either copied verbatim, or with +modifications and/or translated into another language. + +A ``Secondary Section'' is a named appendix or a front-matter section +of the Document that deals exclusively with the relationship of the +publishers or authors of the Document to the Document's overall +subject (or to related matters) and contains nothing that could fall +directly within that overall subject. (Thus, if the Document is in +part a textbook of mathematics, a Secondary Section may not explain +any mathematics.) The relationship could be a matter of historical +connection with the subject or with related matters, or of legal, +commercial, philosophical, ethical or political position regarding +them. + +The ``Invariant Sections'' are certain Secondary Sections whose titles +are designated, as being those of Invariant Sections, in the notice +that says that the Document is released under this License. If a +section does not fit the above definition of Secondary then it is not +allowed to be designated as Invariant. The Document may contain zero +Invariant Sections. If the Document does not identify any Invariant +Sections then there are none. + +The ``Cover Texts'' are certain short passages of text that are listed, +as Front-Cover Texts or Back-Cover Texts, in the notice that says that +the Document is released under this License. A Front-Cover Text may +be at most 5 words, and a Back-Cover Text may be at most 25 words. + +A ``Transparent'' copy of the Document means a machine-readable copy, +represented in a format whose specification is available to the +general public, that is suitable for revising the document +straightforwardly with generic text editors or (for images composed of +pixels) generic paint programs or (for drawings) some widely available +drawing editor, and that is suitable for input to text formatters or +for automatic translation to a variety of formats suitable for input +to text formatters. A copy made in an otherwise Transparent file +format whose markup, or absence of markup, has been arranged to thwart +or discourage subsequent modification by readers is not Transparent. +An image format is not Transparent if used for any substantial amount +of text. A copy that is not ``Transparent'' is called ``Opaque''. + +Examples of suitable formats for Transparent copies include plain +ASCII without markup, Texinfo input format, La@TeX{} input +format, SGML or XML using a publicly available +DTD, and standard-conforming simple HTML, +PostScript or PDF designed for human modification. Examples +of transparent image formats include PNG, XCF and +JPG. Opaque formats include proprietary formats that can be +read and edited only by proprietary word processors, SGML or +XML for which the DTD and/or processing tools are +not generally available, and the machine-generated HTML, +PostScript or PDF produced by some word processors for +output purposes only. + +The ``Title Page'' means, for a printed book, the title page itself, +plus such following pages as are needed to hold, legibly, the material +this License requires to appear in the title page. For works in +formats which do not have any title page as such, ``Title Page'' means +the text near the most prominent appearance of the work's title, +preceding the beginning of the body of the text. + +The ``publisher'' means any person or entity that distributes copies +of the Document to the public. + +A section ``Entitled XYZ'' means a named subunit of the Document whose +title either is precisely XYZ or contains XYZ in parentheses following +text that translates XYZ in another language. (Here XYZ stands for a +specific section name mentioned below, such as ``Acknowledgements'', +``Dedications'', ``Endorsements'', or ``History''.) To ``Preserve the T= itle'' +of such a section when you modify the Document means that it remains a +section ``Entitled XYZ'' according to this definition. + +The Document may include Warranty Disclaimers next to the notice which +states that this License applies to the Document. These Warranty +Disclaimers are considered to be included by reference in this +License, but only as regards disclaiming warranties: any other +implication that these Warranty Disclaimers may have is void and has +no effect on the meaning of this License. + +@item +VERBATIM COPYING + +You may copy and distribute the Document in any medium, either +commercially or noncommercially, provided that this License, the +copyright notices, and the license notice saying this License applies +to the Document are reproduced in all copies, and that you add no other +conditions whatsoever to those of this License. You may not use +technical measures to obstruct or control the reading or further +copying of the copies you make or distribute. However, you may accept +compensation in exchange for copies. If you distribute a large enough +number of copies you must also follow the conditions in section 3. + +You may also lend copies, under the same conditions stated above, and +you may publicly display copies. + +@item +COPYING IN QUANTITY + +If you publish printed copies (or copies in media that commonly have +printed covers) of the Document, numbering more than 100, and the +Document's license notice requires Cover Texts, you must enclose the +copies in covers that carry, clearly and legibly, all these Cover +Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on +the back cover. Both covers must also clearly and legibly identify +you as the publisher of these copies. The front cover must present +the full title with all words of the title equally prominent and +visible. You may add other material on the covers in addition. +Copying with changes limited to the covers, as long as they preserve +the title of the Document and satisfy these conditions, can be treated +as verbatim copying in other respects. + +If the required texts for either cover are too voluminous to fit +legibly, you should put the first ones listed (as many as fit +reasonably) on the actual cover, and continue the rest onto adjacent +pages. + +If you publish or distribute Opaque copies of the Document numbering +more than 100, you must either include a machine-readable Transparent +copy along with each Opaque copy, or state in or with each Opaque copy +a computer-network location from which the general network-using +public has access to download using public-standard network protocols +a complete Transparent copy of the Document, free of added material. +If you use the latter option, you must take reasonably prudent steps, +when you begin distribution of Opaque copies in quantity, to ensure +that this Transparent copy will remain thus accessible at the stated +location until at least one year after the last time you distribute an +Opaque copy (directly or through your agents or retailers) of that +edition to the public. + +It is requested, but not required, that you contact the authors of the +Document well before redistributing any large number of copies, to give +them a chance to provide you with an updated version of the Document. + +@item +MODIFICATIONS + +You may copy and distribute a Modified Version of the Document under +the conditions of sections 2 and 3 above, provided that you release +the Modified Version under precisely this License, with the Modified +Version filling the role of the Document, thus licensing distribution +and modification of the Modified Version to whoever possesses a copy +of it. In addition, you must do these things in the Modified Version: + +@enumerate A +@item +Use in the Title Page (and on the covers, if any) a title distinct +from that of the Document, and from those of previous versions +(which should, if there were any, be listed in the History section +of the Document). You may use the same title as a previous version +if the original publisher of that version gives permission. + +@item +List on the Title Page, as authors, one or more persons or entities +responsible for authorship of the modifications in the Modified +Version, together with at least five of the principal authors of the +Document (all of its principal authors, if it has fewer than five), +unless they release you from this requirement. + +@item +State on the Title page the name of the publisher of the +Modified Version, as the publisher. + +@item +Preserve all the copyright notices of the Document. + +@item +Add an appropriate copyright notice for your modifications +adjacent to the other copyright notices. + +@item +Include, immediately after the copyright notices, a license notice +giving the public permission to use the Modified Version under the +terms of this License, in the form shown in the Addendum below. + +@item +Preserve in that license notice the full lists of Invariant Sections +and required Cover Texts given in the Document's license notice. + +@item +Include an unaltered copy of this License. + +@item +Preserve the section Entitled ``History'', Preserve its Title, and add +to it an item stating at least the title, year, new authors, and +publisher of the Modified Version as given on the Title Page. If +there is no section Entitled ``History'' in the Document, create one +stating the title, year, authors, and publisher of the Document as +given on its Title Page, then add an item describing the Modified +Version as stated in the previous sentence. + +@item +Preserve the network location, if any, given in the Document for +public access to a Transparent copy of the Document, and likewise +the network locations given in the Document for previous versions +it was based on. These may be placed in the ``History'' section. +You may omit a network location for a work that was published at +least four years before the Document itself, or if the original +publisher of the version it refers to gives permission. + +@item +For any section Entitled ``Acknowledgements'' or ``Dedications'', Preser= ve +the Title of the section, and preserve in the section all the +substance and tone of each of the contributor acknowledgements and/or +dedications given therein. + +@item +Preserve all the Invariant Sections of the Document, +unaltered in their text and in their titles. Section numbers +or the equivalent are not considered part of the section titles. + +@item +Delete any section Entitled ``Endorsements''. Such a section +may not be included in the Modified Version. + +@item +Do not retitle any existing section to be Entitled ``Endorsements'' or +to conflict in title with any Invariant Section. + +@item +Preserve any Warranty Disclaimers. +@end enumerate + +If the Modified Version includes new front-matter sections or +appendices that qualify as Secondary Sections and contain no material +copied from the Document, you may at your option designate some or all +of these sections as invariant. To do this, add their titles to the +list of Invariant Sections in the Modified Version's license notice. +These titles must be distinct from any other section titles. + +You may add a section Entitled ``Endorsements'', provided it contains +nothing but endorsements of your Modified Version by various +parties---for example, statements of peer review or that the text has +been approved by an organization as the authoritative definition of a +standard. + +You may add a passage of up to five words as a Front-Cover Text, and a +passage of up to 25 words as a Back-Cover Text, to the end of the list +of Cover Texts in the Modified Version. Only one passage of +Front-Cover Text and one of Back-Cover Text may be added by (or +through arrangements made by) any one entity. If the Document already +includes a cover text for the same cover, previously added by you or +by arrangement made by the same entity you are acting on behalf of, +you may not add another; but you may replace the old one, on explicit +permission from the previous publisher that added the old one. + +The author(s) and publisher(s) of the Document do not by this License +give permission to use their names for publicity for or to assert or +imply endorsement of any Modified Version. + +@item +COMBINING DOCUMENTS + +You may combine the Document with other documents released under this +License, under the terms defined in section 4 above for modified +versions, provided that you include in the combination all of the +Invariant Sections of all of the original documents, unmodified, and +list them all as Invariant Sections of your combined work in its +license notice, and that you preserve all their Warranty Disclaimers. + +The combined work need only contain one copy of this License, and +multiple identical Invariant Sections may be replaced with a single +copy. If there are multiple Invariant Sections with the same name but +different contents, make the title of each such section unique by +adding at the end of it, in parentheses, the name of the original +author or publisher of that section if known, or else a unique number. +Make the same adjustment to the section titles in the list of +Invariant Sections in the license notice of the combined work. + +In the combination, you must combine any sections Entitled ``History'' +in the various original documents, forming one section Entitled +``History''; likewise combine any sections Entitled ``Acknowledgements''= , +and any sections Entitled ``Dedications''. You must delete all +sections Entitled ``Endorsements.'' + +@item +COLLECTIONS OF DOCUMENTS + +You may make a collection consisting of the Document and other documents +released under this License, and replace the individual copies of this +License in the various documents with a single copy that is included in +the collection, provided that you follow the rules of this License for +verbatim copying of each of the documents in all other respects. + +You may extract a single document from such a collection, and distribute +it individually under this License, provided you insert a copy of this +License into the extracted document, and follow this License in all +other respects regarding verbatim copying of that document. + +@item +AGGREGATION WITH INDEPENDENT WORKS + +A compilation of the Document or its derivatives with other separate +and independent documents or works, in or on a volume of a storage or +distribution medium, is called an ``aggregate'' if the copyright +resulting from the compilation is not used to limit the legal rights +of the compilation's users beyond what the individual works permit. +When the Document is included in an aggregate, this License does not +apply to the other works in the aggregate which are not themselves +derivative works of the Document. + +If the Cover Text requirement of section 3 is applicable to these +copies of the Document, then if the Document is less than one half of +the entire aggregate, the Document's Cover Texts may be placed on +covers that bracket the Document within the aggregate, or the +electronic equivalent of covers if the Document is in electronic form. +Otherwise they must appear on printed covers that bracket the whole +aggregate. + +@item +TRANSLATION + +Translation is considered a kind of modification, so you may +distribute translations of the Document under the terms of section 4. +Replacing Invariant Sections with translations requires special +permission from their copyright holders, but you may include +translations of some or all Invariant Sections in addition to the +original versions of these Invariant Sections. You may include a +translation of this License, and all the license notices in the +Document, and any Warranty Disclaimers, provided that you also include +the original English version of this License and the original versions +of those notices and disclaimers. In case of a disagreement between +the translation and the original version of this License or a notice +or disclaimer, the original version will prevail. + +If a section in the Document is Entitled ``Acknowledgements'', +``Dedications'', or ``History'', the requirement (section 4) to Preserve +its Title (section 1) will typically require changing the actual +title. + +@item +TERMINATION + +You may not copy, modify, sublicense, or distribute the Document +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense, or distribute it is void, and +will automatically terminate your rights under this License. + +However, if you cease all violation of this License, then your license +from a particular copyright holder is reinstated (a) provisionally, +unless and until the copyright holder explicitly and finally +terminates your license, and (b) permanently, if the copyright holder +fails to notify you of the violation by some reasonable means prior to +60 days after the cessation. + +Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + +Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, receipt of a copy of some or all of the same material does +not give you any rights to use it. + +@item +FUTURE REVISIONS OF THIS LICENSE + +The Free Software Foundation may publish new, revised versions +of the GNU Free Documentation License from time to time. Such new +versions will be similar in spirit to the present version, but may +differ in detail to address new problems or concerns. See +@uref{http://www.gnu.org/copyleft/}. + +Each version of the License is given a distinguishing version number. +If the Document specifies that a particular numbered version of this +License ``or any later version'' applies to it, you have the option of +following the terms and conditions either of that specified version or +of any later version that has been published (not as a draft) by the +Free Software Foundation. If the Document does not specify a version +number of this License, you may choose any version ever published (not +as a draft) by the Free Software Foundation. If the Document +specifies that a proxy can decide which future versions of this +License can be used, that proxy's public statement of acceptance of a +version permanently authorizes you to choose that version for the +Document. + +@item +RELICENSING + +``Massive Multiauthor Collaboration Site'' (or ``MMC Site'') means any +World Wide Web server that publishes copyrightable works and also +provides prominent facilities for anybody to edit those works. A +public wiki that anybody can edit is an example of such a server. A +``Massive Multiauthor Collaboration'' (or ``MMC'') contained in the +site means any set of copyrightable works thus published on the MMC +site. + +``CC-BY-SA'' means the Creative Commons Attribution-Share Alike 3.0 +license published by Creative Commons Corporation, a not-for-profit +corporation with a principal place of business in San Francisco, +California, as well as future copyleft versions of that license +published by that same organization. + +``Incorporate'' means to publish or republish a Document, in whole or +in part, as part of another Document. + +An MMC is ``eligible for relicensing'' if it is licensed under this +License, and if all works that were first published under this License +somewhere other than this MMC, and subsequently incorporated in whole +or in part into the MMC, (1) had no cover texts or invariant sections, +and (2) were thus incorporated prior to November 1, 2008. + +The operator of an MMC Site may republish an MMC contained in the site +under CC-BY-SA on the same site at any time before August 1, 2009, +provided the MMC is eligible for relicensing. + +@end enumerate + +@page +@heading ADDENDUM: How to use this License for your documents + +To use this License in a document you have written, include a copy of +the License in the document and put the following copyright and +license notices just after the title page: + +@smallexample +@group + Copyright (C) @var{year} @var{your name}. + Permission is granted to copy, distribute and/or modify this document + under the terms of the GNU Free Documentation License, Version 1.3 + or any later version published by the Free Software Foundation; + with no Invariant Sections, no Front-Cover Texts, and no Back-Cover + Texts. A copy of the license is included in the section entitled ``GN= U + Free Documentation License''. +@end group +@end smallexample + +If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, +replace the ``with@dots{}Texts.''@: line with this: + +@smallexample +@group + with the Invariant Sections being @var{list their titles}, with + the Front-Cover Texts being @var{list}, and with the Back-Cover Text= s + being @var{list}. +@end group +@end smallexample + +If you have Invariant Sections without Cover Texts, or some other +combination of the three, merge those two alternatives to suit the +situation. + +If your document contains nontrivial examples of program code, we +recommend releasing these examples in parallel under your choice of +free software license, such as the GNU General Public License, +to permit their use in free software. + +@c Local Variables: +@c ispell-local-pdict: "ispell-dict" +@c End: diff --git a/doc/shepherd.texi b/doc/shepherd.texi new file mode 100644 index 0000000..5dc5f9c --- /dev/null +++ b/doc/shepherd.texi @@ -0,0 +1,1593 @@ +\input texinfo @c -*- texinfo -*- +@c shepherd.texi -- The documentation in Texinfo format. +@documentencoding UTF-8 +@setfilename shepherd.info +@settitle The GNU Shepherd Manual + +@include version.texi +@set OLD-YEARS 2002, 2003 +@set NEW-YEARS 2013, 2016 + +@copying +Copyright @copyright{} @value{OLD-YEARS} Wolfgang J@"ahrling@* +Copyright @copyright{} @value{NEW-YEARS} Ludovic Court=C3=A8s + +Permission is granted to copy, distribute and/or modify this document +under the terms of the GNU Free Documentation License, Version 1.3 or +any later version published by the Free Software Foundation; with no +Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A +copy of the license is included in the section entitled ``GNU Free +Documentation License''. +@end copying + +@dircategory System software +@direntry +* shepherd: (shepherd). The Shepherd service manager. +* herd: (shepherd)Invoking herd + Controlling the Shepherd service manager. +* reboot: (shepherd)Invoking reboot + Rebooting a Shepherd-controlled system. +* halt: (shepherd)Invoking halt + Turning off a Shepherd-controlled system. +@end direntry + +@titlepage +@title The GNU Shepherd Manual +@subtitle For use with the GNU Shepherd @value{VERSION} +@subtitle Last updated @value{UPDATED} + +@author Wolfgang J@"ahrling +@author Ludovic Court=C3=A8s + +@insertcopying +@end titlepage + +@contents + + +@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + +@ifnottex +@node Top +@top The GNU Shepherd Manual + +This manual documents the GNU@tie{}Shepherd version @value{VERSION}, a +service manager for the GNU system. + +@menu +* Introduction:: Introduction to the Shepherd service manager. +* Jump Start:: How to do simple things with the Shepherd. +* herd and shepherd:: User interface to service management. +* Services:: Details on services. +* Runlevels:: Details on runlevels. +* Misc Facilities:: Generally useful things provided by the Shepherd. +* Internals:: Hacking shepherd. + +* GNU Free Documentation License:: The license of this manual. +* Concept Index:: +* Procedure and Macro Index:: +* Variable Index:: +* Type Index:: +@end menu +@end ifnottex + +@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + +@node Introduction +@chapter Introduction + +@cindex service manager +This manual documents the GNU@tie{}Daemon Shepherd, or GNU@tie{}Shepherd +for short. The Shepherd looks after system services, typically @dfn{dae= mons}. +It is used to start and stop them in a reliable +fashion. For instance it will dynamically determine and start any +other services that our desired service depends upon. As another +example, the Shepherd might detect conflicts among services. In this +situation it would simply prevent the conflicting services from +running concurrently. + +The Shepherd is the @dfn{init system} of the GNU operating system---it i= s the +first user process that gets started, typically with PID 1, and runs +as @code{root}. Normally the purpose of init systems is to manage all +system-wide services, but the Shepherd can also be a useful tool assisti= ng +unprivileged users in the management of their own daemons. + +Flexible software requires some time to master and +the Shepherd is no different. But don't worry: this manual should allow= you to +get started quickly. Its first chapter is designed as a practical +introduction to the Shepherd and should be all you need for everyday use +(@pxref{Jump Start}). In chapter two we will describe the +@command{herd} and @command{shepherd} programs, and their relationship, = in +more detail (@ref{herd and shepherd}). Subsequent chapters provide a fu= ll +reference manual and plenty of examples, covering all of Shepherd's +capabilities. Finally, the last chapter provides information for +those souls brave enough to hack the Shepherd itself. + +@cindex dmd +The Shepherd was formerly known as ``dmd'', which stands for @dfn{Daemon +Managing Daemons} (or @dfn{Daemons-Managing Daemon}?). + +@cindex Guile +@cindex Scheme +@cindex GOOPS +This program is written in Guile, an implementation of the +Scheme programming language, using the GOOPS extension for +object-orientation. Guile is also the Shepherd's configuration language= . +@xref{Introduction,,, guile, GNU Guile Reference Manual}, for an +introduction to Guile. We have tried to +make the Shepherd's basic features as accessible as possible---you shoul= d be +able to use these even if you do not know how to program in Scheme. A +basic grasp of Guile and GOOPS is required only if you wish to make +use of the Shepherd's more advanced features. + +@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + +@node Jump Start +@chapter Jump Start + +@cindex prefix +This chapter gives a short overview of the Shepherd. It is enough if yo= u just +need the basic features of it. As it is not assumed that readers are +familiar with all the involved issues, a very experienced user might +be annoyed by the often very detailed descriptions in this +introduction. Those users are encouraged to just skip to the +reference section. + +Note that all the full file names in the following text are based on +the assumption that you have installed the Shepherd with an empty prefix= . If +your the Shepherd installation for example resides in @code{/usr/local} +instead, add this directory name in front of the absolute file names +mentioned below. + +@cindex Configuration file +When @command{shepherd} gets started, it reads and evaluates a +configuration file. When it is started with superuser priviledges, it +tries to use @code{/etc/shepherd.scm}. When started as normal user, it +looks for a file called @code{$XDG_CONFIG_HOME/shepherd/init.scm}. If +the @code{XDG_CONFIG_HOME} environment variable is not defined, +@code{$HOME/.config/shepherd/init.scm} is used instead. With the option +@code{--config} (or, for short, @code{-c}), you can specify where to +look instead. So if you want to start @command{shepherd} with an +alternative file, use one of the following commands: + +@example +shepherd --config=3D/etc/shepherd.scm.old +shepherd -c /etc/shepherd.scm.old +@end example + +@cindex Starting a service +As the final ``d'' suggests, @command{shepherd} is just +a daemon that (usually) runs in the +background, so you will not interact with it directly. After it is +started, @command{shepherd} will listen on a socket special file, usuall= y +@code{/var/run/shepherd/socket}, for further commands. You use the tool +@dfn{herd} to send these commands to @command{shepherd}. Usage of herd = is simple and +straightforward: To start a service called @code{apache}, you use: + +@example +herd start apache +@end example + +@cindex Status (of services) +@cindex Service status +When you do this, all its dependencies will get resolved. For +example, a webserver is quite likely to depend on working networking, +thus it will depend on a service called @code{networking}. So if you +want to start @code{apache}, and @code{networking} is not yet running, i= t +will automatically be started as well. The current status of all the +services defined in the configuration file can be queried like this: + +@example +herd status +@end example + +@noindent +Or, to get additional details about each service, run: + +@example +herd detailed-status +@end example + +@noindent +In this example, this would show the @code{networking} and @code{apache} +services as started. If you just want to know the status of the +@code{apache} service, run: + +@example +herd status apache +@end example + +@cindex Stopping a service +You can stop +a service and all the services that depend on it will be stopped. +Using the example above, if you stop @code{networking}, the service +@code{apache} will be stopped as well---which makes perfect sense, +as it cannot work without the network being up. To actually stop a +service, you use the following, probably not very surprising, command: + +@example +herd stop networking +@end example + +There are two more actions you can perform on every service: The +actions @code{enable} and @code{disable} are used to prevent and allow +starting of the particular service. If a service is intended to be +restarted whenever it terminates (how this can be done will not be +covered in this introduction), but it is respawning too often in a +short period of time (by default 5 times in 5 seconds), it will +automatically be disabled. After you have fixed the problem that +caused it from being respawned too fast, you can start it again with +the commands: + +@example +herd enable foo +herd start foo +@end example + +@cindex virtual services +@cindex fallback services +But there is far more you can do than just that. Services can not +only simply depend on other services, they can also depend on +@emph{virtual} services. A virtual service is a service that is +provided by one or more service additionally. For instance, a service +called @code{exim} might provide the virtual service +@code{mailer-daemon}. That could as well be provided by a service +called @code{smail}, as both are mailer-daemons. If a service needs +any mailer-daemon, no matter which one, it can just depend on +@code{mailer-daemon}, and one of those who provide it gets started (if +none is running yet) when resolving dependencies. The nice thing is +that, if trying to start one of them fails, @command{shepherd} will go o= n and try to +start the next one, so you can also use virtual services for +specifying @emph{fallbacks}. + +Additionally to all that, you can perform service-specific actions. +Coming back to our original example, @code{apache} is able to +reload its modules, therefore the action @code{reload-modules} might +be available: + +@example +herd reload-modules apache +@end example + +The service-specific actions can only be used when the service is +started, i.e. the only thing you can do to a stopped service is +starting it. An exception exists, see below. (If you may at some +point find this too restrictive because you want to use variants of +the same service which are started in different ways, consider using +different services for those variants instead, which all provide the +same virtual service and thus conflict with each other, if this is +desired. That's one of the reasons why virtual services exist, after +all.) + +There are two actions which are special, because even if services +can implement them on their own, a default implementation is provided +by @command{shepherd} (another reason why they are special is that the d= efault +implementations can be called even when the service is not running; +this inconsistency is just to make it more intuitive to get +information about the status of a service, see below). + +These actions are @code{restart} and @code{status}. The default +implementation of @code{restart} calls @code{stop} and @code{start} on +the affected service in order, the @code{status} action displays some +general information about the service, like what it provides, what it +depends on and with which other services it conflicts (because they +provide a virtual service that is also provided by that particular +service). + +Another special action is @code{list-actions}, which displays a list +of the additional actions a service provides; obviously, it can also +be called when the service is not running. Services cannot provide +their own implementation of @code{list-actions}. + +A special service is @code{root}, which is used for controlling the +Shepherd itself. You can also reference to this service as +@code{shepherd}. It implements various actions. For example, the +@code{status} action displays which services are started and which ones +are stopped, whereas @code{detailed-status} has the effect of applying +the default implementation of @code{status} to all services one after +another. The @code{load} action is unusual insofar as it shows a +feature that is actually available to all services, but which we have +not seen yet: It takes an additional argument. You can use @code{load} +to load arbitrary code into the Shepherd at runtime, like this: + +@example +herd load shepherd ~/additional-services.scm +@end example + +This is enough now about the @command{herd} and @command{shepherd} progr= ams, we +will now take a look at how to configure the Shepherd. In the configura= tion +file, we need mainly the definition of services. We can also do +various other things there, like starting a few services already. + +FIXME: Finish. For now, look at the @code{examples/} subdirectory. + +@example +... +@end example + +Ok, to summarize: + +@itemize @bullet +@item +@command{shepherd} is a daemon, @command{herd} the program that controls= it. +@item +You can start, stop, restart, enable and disable every service, as +well as display its status. +@item +You can perform additional service-specific actions, which you can +also list. +@item +Actions can have arguments. +@item +You can display the status of a service, even if the service does not +provide a specific implementation for this action. The same is true +for restarting. +@item +The @code{root}/@code{shepherd} service is used to control +@command{shepherd} itself. +@end itemize + +@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + +@node herd and shepherd +@chapter @command{herd} and @command{shepherd} + +@cindex herd +@cindex shepherd +@cindex daemon +@cindex daemon controller +@cindex relative file names +@cindex herding, of daemons +The daemon that runs in the background and is responsible for +controlling the services is @command{shepherd}, while the user interface +tool is called @command{herd}: it's the command that allows you to +actually @emph{herd} your daemons@footnote{ +@cindex deco, daemon controller +In the past, when the +GNU@tie{}Shepherd was known as GNU@tie{}dmd, the @command{herd} command +was called @code{deco}, for @dfn{DaEmon COntroller}.}. To perform an +action, like stopping a service or calling an action of a service, you +use the herd program. It will communicate with shepherd over a Unix +Domain Socket. + +Thus, you start @command{shepherd} once, and then always use herd whenev= er you want +to do something service-related. Since herd passes its current +working directory to @command{shepherd}, you can pass relative file name= s without +trouble. Both @command{shepherd} and herd understand the standard argum= ents +@code{--help}, @code{--version} and @code{--usage}. + + +@menu +* Invoking shepherd:: How to start the service damon. +* Invoking herd:: Controlling daemons. +* Invoking reboot:: Rebooting a shepherd-controlled system. +* Invoking halt:: Turning off a shepherd-controlled system= . +@end menu + +@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + +@node Invoking shepherd +@section Invoking @command{shepherd} + +@cindex @command{shepherd} Invocation +@cindex invoking @command{shepherd} +The @code{shepherd} program has the following synopsis: + +@example +shepherd [@var{option}@dots{}] +@end example + +It accepts the following options: + +@table @samp +@item -c @var{file} +@itemx --config=3D@var{file} +Read and evaluate @var{file} as the configuration script on startup. + +@var{file} is evaluated in the context of a fresh module where bindings +from the @code{(shepherd service)} module and Guile's @code{(oop goops)}= are +available, in addition to the default set of Guile bindings. In +particular, this means that code in @var{file} may use +@code{register-services}, the @code{} class, and related tools +(@pxref{Services}). + +@item -I +@itemx --insecure +@cindex security +@cindex insecure +Do not check if the directory where the socket---our communication +rendez-vous with @command{herd}---is located has permissions @code{700}. +If this option is not specified, @command{shepherd} will abort if the +permissions are not as expected. + +@item -l [@var{file}] +@itemx --logfile[=3D@var{file}] +@cindex logging +@cindex log file +Log output into @var{file}, or if @var{file} is not given, +@code{/var/log/shepherd.log} when running as superuser, +@code{$XDG_CONFIG_HOME/shepherd/shepherd.log} otherwise. + +@item --pid[=3D@var{file}] +When @command{shepherd} is ready to accept connections, write its PID to= @var{file} or +to the standard output if @var{file} is omitted. + +@item -p [@var{file}] +@itemx --persistency[=3D@var{file}] +@c FIXME-CRITICAL + +@item -s @var{file} +@itemx --socket=3D@var{file} +@cindex socket special file +Receive further commands on the socket special file @var{file}. If +this option is not specified, @file{@var{localstatedir}/run/shepherd/soc= ket} is +taken. + +If @code{-} is specified as file name, commands will be read from +standard input, one per line, as would be passed on a @command{herd} +command line (@pxref{Invoking herd}). + +@item --quiet +Synonym for @code{--silent}. + +@end table + +@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + +@node Invoking herd +@section Invoking herd + +@cindex herd +The @command{herd} command is a generic client program to control a +running instance of @command{shepherd} (@pxref{Invoking shepherd}). It = has the +following synopsis: + +@example +herd [@var{option}@dots{}] @var{action} [@var{service} [@var{arg}@dots{}= ]] +@end example + +It causes the @var{action} of the @var{service} to be invoked. When +@var{service} is omitted and @var{action} is @code{status} or +@code{detailed-status}, the @code{root} service is used@footnote{This +shorthand does not work for other actions such as @code{stop}, because +inadvertently typing @code{herd stop} would stop all the services, which +could be pretty annoying.} (@pxref{The root and unknown services}, for +more information on the @code{root} service.) + +For each action, you should pass the appropriate @var{arg}s. Actions +that are available for every service are @code{start}, @code{stop}, +@code{restart}, @code{status}, @code{enable}, @code{disable}, and +@code{doc}. + +If you pass a file name as an @var{arg}, it will be passed as-is to +the Shepherd, thus if it is not an absolute name, it is local to the cur= rent +working directory of @command{shepherd}, not to herd. + +The @code{herd} command understands the following option: + +@table @samp + +@item -s @var{file} +@itemx --socket=3D@var{file} +Send commands to the socket special file @var{file}. If this option is +not specified, @file{@var{localstatedir}/run/shepherd/socket} is taken. + +@end table + +The @code{herd} command returns zero on success, and a non-zero exit +code on failure. In particular, it returns a non-zero exit code when +@var{action} or @var{service} does not exist and when the given action +failed. + + +@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + +@node Invoking reboot +@section Invoking reboot + +@cindex herd +The @command{reboot} command is a convenience client program to instruct +the Shepherd (when used as an init system) to stop all running services = and +reboot the system. It has the following synopsis: + +@example +reboot [@var{option}@dots{}] +@end example + +It is equivalent to running @command{herd stop shepherd}. The +@code{reboot} command understands the following option: + +@table @samp + +@item -s @var{file} +@itemx --socket=3D@var{file} +Send commands to the socket special file @var{file}. If this option is +not specified, @file{@var{localstatedir}/run/shepherd/socket} is taken. + +@end table + +@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + +@node Invoking halt +@section Invoking halt + +@cindex herd +The @command{halt} command is a convenience client program to instruct +the Shepherd (when used as an init system) to stop all running services = and turn +off the system. It has the following synopsis: + +@example +halt [@var{option}@dots{}] +@end example + +It is equivalent to running @command{herd power-off shepherd}. As +usual, the @code{halt} command understands the following option: + +@table @samp + +@item -s @var{file} +@itemx --socket=3D@var{file} +Send commands to the socket special file @var{file}. If this option is +not specified, @file{@var{localstatedir}/run/shepherd/socket} is taken. + +@end table + + +@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + +@node Services +@chapter Services + +@cindex service +@tindex +The @dfn{service} is obviously a very important concept of the Shepherd.= On the +Guile level, a service is represented as an instance of +@code{}, a GOOPS class (@pxref{GOOPS,,, guile, GNU Guile +Reference Manual}). When creating an instance of it, you can specify +the initial values of its slots, and you actually must do this for some +of the slots. + +The @code{} class and its associated procedures and methods are +defined in the @code{(shepherd service)} module. + +@menu +* Slots of services:: What a object consists of. +* Methods of services:: What you can do with a object= . +* Service Convenience:: How to conveniently work with services. +* Service De- and Constructors:: Commonly used ways of starting and + stopping services. +* Service Examples:: Examples that show how services are use= d. +* The root and unknown services:: Special services in the Shepherd. +@end menu + +@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + +@node Slots of services +@section Slots of services + +@cindex , slots of +@cindex slots of +A service has the following slots, all of which can be initialized +with a keyword (i.e. @code{#:provides}, used when creating the object) +of the same name, except where stated otherwise. You should not +access them directly with @code{slot-ref} or @code{slot-set!} +usually, use the methods of the service class @ref{Methods of +services} instead. + +@itemize @bullet +@item +@vindex provides (slot of ) +@cindex canonical names of services +@code{provides} is a list of symbols that are provided by the service. +A symbol can only be provided by one service running at a time, +i.e. if two services provide the same symbol, only one of them can +run, starting the other one will fail. Therefore, these symbols are +mainly used to denote conflicting services. The first symbol in the +list is the canonical name for the service, thus it must be unique. +This slot has no default value and must therefore be initialized. + +@item +@vindex requires (slot of ) +@code{requires} is, like @code{provides}, a list of symbols that +specify services. In this case, they name what this service depends +on, i.e. before the service can be started, services that provide +those symbols must be started. If a required symbol is provided by +several services, one will be started. By default, this slot +contains the empty list. + +@item +@vindex running (slot of ) +@cindex Hook for individual services +@code{running} is a hook that can be used by each service in its own +way. The default value is @code{#f}, which indicates that the service +is not running. When an attempt is made to start the service, it will +be set to the return value of the procedure in the @code{start} slot. +It will also be passed as an argument to the procedure in the +@code{stop} slot. This slot can not be initialized with a keyword. + +@item +@vindex respawn? (slot of ) +@cindex Respawning services +@code{respawn?} specifies whether the service should be respawned by +the Shepherd. If this slot has the value @code{#t}, then assume the +@code{running} slot specifies a child process PID and restart the +service if that process terminates. Otherwise this slot is @code{#f}, +which is the default. See also the @code{last-respawns} slot. + +@item +@vindex start (slot of ) +@cindex Starting a service +@cindex Service constructor +@code{start} contains the ``constructor'' for the service, which will +be called to start the service. (Therefore, it is not a constructor +in the sense that it initializes the slots of a @code{} +object.) This must be a procedure that accepts any amount of +arguments, which will be the additional arguments supplied by the +user. If the starting attempt failed, it must return @code{#f}. The +value will be stored in the @code{running} slot. The default value is +a procedure that returns @code{#t} and performs no further actions, +therefore it is desirable to specify a different one usually. + +@item +@vindex stop (slot of ) +@cindex Stoping a service +@cindex Service destructor +@code{stop} is, similar to @code{start}, a slot containing a +procedure. But in this case, it gets the current value of the +@code{running} slot as first argument and the user-supplied arguments +as further arguments; it gets called to stop the service. Its return +value will again be stored in the @code{running} slot, so that it +should return @code{#f} if it is now possible again to start the +service at a later point. The default value is a procedure that +returns @code{#f} and performs no further actions. + +@item +@vindex actions (slot of ) +@cindex Actions of services +@cindex Service actions +@code{actions} specifies the additional actions that can be performed +on a service when it is running. A typical example for this is the +@code{restart} action. The macro @code{make-actions} @ref{Service +Convenience} is provided to abstract the actual data representation +format for this slot. (It actually is a hash currently.) + +@item +@vindex enabled? (slot of ) +@code{enabled?} cannot be initialized with a keyword, and contains +@code{#t} by default. When the value becomes @code{#f} at some point, +this will prevent the service from getting started. A service can be +enabled and disabled with the methods @code{enable} and +@code{disable}, respectively @ref{Methods of services}. + +@item +@vindex last-respawns (slot of ) +@code{last-respawns} cannot be initialized with a keyword and is only +ever used when the @code{respawn?} slot contains @code{#t}; it is a +circular list with @code{(car respawn-limit)} elements, where each +element contains the time when it was restarted, initially all 0, +later a time in seconds since the Epoch. The first element is the one +that contains the oldest one, the last one the newest. + +@item +@vindex stop-delay? (slot of ) +@code{stop-delay?} being false causes the @code{stop} slot to be +unused; instead, stopping the service will just cause the +@code{waiting-for-termination?} slot be set to @code{#t}. + +@item +@vindex waiting-for-termination? (slot of ) +@code{waiting-for-termination?} cannot be initialized with a keyword +and should not be used by others, it is only used internally for +respawnable services when the @code{stop-delay?} slot contains a true +value. @code{waiting-for-termination?} contains @code{#t} if the +service is still running, but the user requested that it be stopped, +in which case if the service terminates the next time, the respawn +handler will not start it again. + +otherwise @code{#f}. + +@end itemize + +@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + +@node Methods of services +@section Methods of services + +@deffn {method} start (obj ) +Start the service @var{obj}, including all the services it depends on. +It tries quite hard to do this: When a service that provides a +required symbol can not be started, it will look for another service +that also provides this symbol, until starting one such service +succeeds. There is some room for theoretical improvement here, of +course, but in pratice the current strategy already works very well. +This method returns the new value of the @code{running} slot +@ref{Slots of services}, which is @code{#f} if the service could not +be started. +@end deffn + +@deffn {method} stop (obj ) +This will stop the service @var{obj}, trying to stop services that +depend in it first, so they can be shutdown cleanly. If this will +fail, it will continue anyway. Stopping of services should usually +succeed, though. Otherwise, the behaviour is very similar to the +@code{start} method. The return value is also the new @code{running} +value, thus @code{#f} if the service was stopped. +@end deffn + +@deffn {method} action (obj ) the-action . args +Calls the action @var{the-action} (a symbol) of the service @var{obj}, +with the specified @var{args}, which have a meaning depending on the +particular action. +@end deffn + +@deffn {method} conflicts-with (obj ) +Returns a list of the canonical names of services that conflict with +the service @var{obj}. +@end deffn + +@deffn {method} canonical-name (obj ) +Returns the canonical name of @var{obj}, which is the first element of +the @code{provides} list. +@end deffn + +@deffn {method} provided-by (obj ) +Returns which symbols are provided by @var{obj}. +@end deffn + +@deffn {method} required-by (obj ) +Returns which symbols are required by @var{obj}. +@end deffn + +@deffn {method} running? (obj ) +Returns whether the service @var{obj} is running. +@end deffn + +@deffn {method} respawn? (obj ) +Returns whether the service @var{obj} should be respawned if it +terminates. +@end deffn + +@deffn {method} default-display-status (obj ) +Display status information about @var{obj}. This method is called +when the user performs the action @code{status} on @var{obj}, but +there is no specific implementation given for it. It is also called +when @code{detailed-status} is applied on the @code{root} service. +@end deffn + +@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + +@node Service Convenience +@section Service Convenience + +In addition to the facilities listed below, there are also some +procedures that provide commonly needed constructors and destructors +for services @ref{Service De- and Constructors}. + +@deffn {procedure} register-services . services +Register all @var{services}, so that they can be taken into account +when trying to resolve dependencies. +@end deffn + +@deffn {procedure} lookup-services name +Return a list of all registered services which provide the symbol +@var{name}. +@end deffn + +@deffn {macro} make-actions (name proc) ... +This macro is used to create a value for the @code{actions} slot of a +service object @ref{Slots of services}. Each @var{name} is a symbol +and each @var{proc} the corresponding procedure that will be called to +perform the action. A @var{proc} has one argument, which will be the +current value of the @code{running} slot of the service. +@end deffn + +@deffn {method} start (obj ) +Start a registered service providing @var{obj}. +@end deffn + +@deffn {method} stop (obj ) +Stop a registered service providing @var{obj}. +@end deffn + +@deffn {method} action (obj ) the-action . args +The same as the @code{action} method of class @code{}, but +uses a service that provides @var{obj} and is running. +@end deffn + +@deffn {procedure} for-each-service proc +Call @var{proc}, a procedure taking one argument, once for each +registered service. +@end deffn + +@deffn {procedure} find-running services +Check if any of @var{services} is running. If this is the case, +return its canonical name. If not, return @code{#f}. Only the first +one will be returned; this is because this is mainly intended to be +applied on the return value of @code{lookup-services}. +@end deffn + +@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + +@node Service De- and Constructors +@section Service De- and Constructors + +@cindex generating constructors +@cindex generating destructors +@cindex constructors, generation of +@cindex destructors, generation of +All of the procedures listed below return procedures generated from +the supplied arguments. These procedures take one argument in the +case of destructors and no arguments in the case of constructors. + +@deffn {procedure} make-system-constructor @var{command}@dots{} +The returned procedure will execute @var{command} in a shell and +return @code{#t} if execution was successful, otherwise @code{#f}. +For convenience, it takes multiple arguments which will be +concatenated first. +@end deffn + +@deffn {procedure} make-system-destructor @var{command}@dots{} +Similar to @code{make-system-constructor}, but returns @code{#f} if +execution of the @var{command} was successful, @code{#t} if not. +@end deffn + +@deffn {procedure} make-forkexec-constructor @var{command} @ + [#:user #f] @ + [#:group #f] @ + [#:pid-file #f] @ + [#:directory (default-service-directory)] @ + [#:environment-variables (default-environment-variables)] +Return a procedure that forks a child process, closes all file +descriptors except the standard output and standard error descriptors, s= ets +the current directory to @var{directory}, changes the environment to +@var{environment-variables} (using the @code{environ} procedure), sets t= he +current user to @var{user} and the current group to @var{group} unless t= hey +are @code{#f}, and executes @var{command} (a list of strings.) The resu= lt of +the procedure will be the PID of the child process. + +When @var{pid-file} is true, it must be the name of a PID file +associated with the process being launched; the return value is the PID +read from that file, once that file has been created. +@end deffn + +@deffn {procedure} make-kill-destructor [@var{signal}] +Returns a procedure that sends @var{signal} to the pid which it takes +as argument. This @emph{does} work together with respawning services, +because in that case the @code{stop} method of the @code{} +class sets the @code{running} slot to @code{#f} before actually +calling the destructor; if it would not do that, killing the process +in the destructor would immediately respawn the service. +@end deffn + +The @code{make-forkexec-constructor} procedure builds upon the following +procedures. + +@deffn {procedure} exec-command @var{command} @ + [#:user #f] @ + [#:group #f] @ + [#:directory (default-service-directory)] @ + [#:environment-variables (default-environment-variables)] +@deffnx {procedure} fork+exec-command @var{command} @ + [#:user #f] @ + [#:group #f] @ + [#:directory (default-service-directory)] @ + [#:environment-variables (default-environment-variables)] +Run @var{command} as the current process from @var{directory}, and with +@var{environment-variables} (a list of strings like @code{"PATH=3D/bin"}= .) +File descriptors 1 and 2 are kept as is, whereas file descriptor 0 +(standard input) points to @file{/dev/null}; all other file descriptors +are closed prior to yielding control to @var{command}. + +By default, @var{command} is run as the current user. If the +@var{user} keyword argument is present and not false, change to +@var{user} immediately before invoking @var{command}. @var{user} may +be a string, indicating a user name, or a number, indicating a user +ID. Likewise, @var{command} will be run under the current group, +unless the @var{group} keyword argument is present and not false. + +@code{fork+exec-command} does the same as @code{exec-command}, but in +a separate process whose PID it returns. +@end deffn + +@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + +@node Service Examples +@section Service Examples + +FIXME: This needs a lot of work. + +You can create a service and then register it this way: + +@lisp +(define apache (make + #:provides '(apache) + #:start (...) + #:stop (...))) +(register-services apache) +@end lisp + +However, as you usually won't need a variable for the service, you can +pass it directly to @code{register-services}. Here is an example that +also specifies some more initial values for the slots: + +@lisp +(register-services + (make + #:provides '(apache-2.0 apache httpd) + #:requires '() + #:start (...) + #:stop (...) + #:actions (make-actions + (reload-modules (...)) + (restart (...))))) +@end lisp + +@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + +@node The root and unknown services +@section The @code{root} and @code{unknown} services + +@cindex root service +@cindex special services +The service @code{root} is special, because it is used to control the +Shepherd itself. It has an alias @code{shepherd}. It provides the +following actions (in addition to @code{enable}, @code{disable} and +@code{restart} which do not make sense here). + +@table @code +@item status +Displays which services are started and which ones are not. + +@item detailed-status +Displays detailed information about every registered service. + +@item load @var{file} +Evaluate the Scheme code in @var{file} in a fresh module that uses the +@code{(oop goops)} and @code{(shepherd services)} modules---as with the +@code{--config} option of @command{shepherd} (@pxref{Invoking shepherd})= . + +@item unload @var{service-name} +Attempt to remove the service identified by @var{service-name}. +@command{shepherd} will first stop the service, if necessary, and then +remove it from the list of registered services. Any services +depending upon @var{service-name} will be stopped as part of this +process. + +If @var{service-name} simply does not exist, output a warning and do +nothing. If it exists, but is provided by several services, output a +warning and do nothing. This latter case might occur for instance with +the fictional service @code{web-server}, which might be provided by both +@code{apache} and @code{nginx}. If @var{service-name} is the special +string and @code{all}, attempt to remove all services except for the She= pherd +itself. + +@item reload @var{file-name} +Unload all known optional services using unload's @code{all} option, +then load @var{file-name} using @code{load} functionality. If +file-name does not exist or @code{load} encounters an error, you may +end up with no defined services. As these can be reloaded at a later +stage this is not considered a problem. If the @code{unload} stage +fails, @code{reload} will not attempt to load @var{file-name}. + +@item daemonize +Fork and go into the background. This should be called before +respawnable services are started, as otherwise we would not get the +@code{SIGCHLD} signals when they terminate. + +@item enable-persistency +When terminating, safe the list of running services in a file. +@c FIXME-CRITICAL: How can we specify which one? + +@item disable-persistency +Don't safe the list of running services when terminating. + +@end table + +@cindex unknown service +@cindex fallback service +The @code{unknown} service must be defined by the user and if it +exists, is used as a fallback whenever we try to invoke an unknown +action of an existing service or use a service that does not exist. +This is useful only in few cases, but enables you to do various sorts +of unusual things. + +@c FIXME-CRITICAL: finish + +@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + +@node Runlevels +@chapter Runlevels + +RUNLEVELS DO NOT WORK YET! Do not use them! Ignore this section! + +@cindex runlevel +@tindex +A @dfn{runlevel} makes it easier to start and stop groups of services, +to bring the system into a certain state. An object of class +@code{} is an abstract runlevel, and has the following +methods: + +@deffn {method} enter (rl ) services +This will be called when the runlevel should be entered. +@var{services} is the list of the currently running services. +@end deffn + +@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + +@node Misc Facilities +@chapter Misc Facilities + +This is a list of facilities which are available to code running +inside of the Shepherd and is considered generally useful, but is not di= rectly +related to one of the other topic covered in this manual. + +@menu +* Errors:: Signalling, handling and ignoring errors. +* Communication:: Input/Output in various ways. +* Others:: Stuff that is useful, but is homeless. +@end menu + +@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + +@node Errors +@section Errors + +@cindex assertions +@deffn {macro} assert expr +If @var{expr} yields @code{#f}, display an appropriate error +message and throw an @code{assertion-failed} exception. +@end deffn + +@deffn {procedure} caught-error key args +Tell the Shepherd that a @var{key} error with @var{args} has occured. T= his is +the simplest way to cause caught error result in uniformly formated +warning messages. The current implementation is not very good, +though. +@end deffn + +@deffn {procedure} call/cc proc +An alias for @code{call-with-current-continuation}. +@end deffn + +@deffn {procedure} call/ec proc +A simplistic implementation of the nonstandard, but popular procedure +@code{call-with-escape-continuation}, i.e. a @code{call/cc} for +outgoing continuations only. Note that the variant included in the Shep= herd is +not aware of @code{dynamic-wind} at all and does not yet support +returning multiple values. +@end deffn + +@cindex system errors +@deffn {macro} without-system-error expr@dots{} +Evaluates the @var{expr}s, not going further if a system error occurs, +but also doing nothing about it. +@end deffn + +@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + +@node Communication +@section Communication + +The @code{(shepherd comm)} module provides primitives that allow clients= such +as @command{herd} to connect to @command{shepherd} and send it commands = to +control or change its behavior (@pxref{Slots of services, actions of +services}). + +@tindex +Currently, clients may only send @dfn{commands}, represented by the +@code{} type. Each command specifies a service it +applies to, an action name, a list of strings to be used as arguments, +and a working directory. Commands are instantiated with +@code{shepherd-command}: + +@deffn {procedure} shepherd-command @var{action} @var{service} @ + [#:@var{arguments} '()] [#:@var{directory} (getcwd)] +Return a new command (a @code{}) object for +@var{action} on @var{service}. +@end deffn + +@noindent +Commands may then be written to or read from a communication channel +with the following procedures: + +@deffn {procedure} write-command @var{command} @var{port} +Write @var{command} to @var{port}. +@end deffn + +@deffn {procedure} read-command @var{port} +Receive a command from @var{port} and return it. +@end deffn + +In practice, communication with @command{shepherd} takes place over a +Unix-domain socket, as discussed earlier (@pxref{Invoking shepherd}). +Clients may open a connection with the procedure below. + +@deffn {procedure} open-connection [@var{file}] +Open a connection to the daemon, using the Unix-domain socket at +@var{file}, and return the socket. + +When @var{file} is omitted, the default socket is used. +@end deffn + +@cindex output +The daemon writes output to be logged or passed to the +currently-connected client using @code{local-output}: + +@deffn {procedure} local-output format-string . args +This procedure should be used for all output operations in the Shepherd.= It +outputs the @var{args} according to the @var{format-string}, then +inserts a newline. It writes to whatever is the main output target of +the Shepherd, which might be multiple at the same time in future version= s. +@end deffn + +@cindex protocol, between @command{shepherd} and its clients +Under the hood, @code{write-command} and @code{read-command} write/read +commands as s-expressions (sexps). Each sexp is intelligible and +specifies a protocol version. The idea is that users can write their +own clients rather than having to invoke @command{herd}. For instance, +when you type @command{herd status}, what is sent over the wire is the +following sexp: + +@lisp +(shepherd-command + (version 0) + (action status) (service root) + (arguments ()) (directory "/data/src/dmd")) +@end lisp + +The reply is also an sexp, along these lines: + +@lisp +(reply (version 0) + (result (((service @dots{}) @dots{}))) + (error #f) (messages ())) +@end lisp + +This reply indicates that the @code{status} action was successful, +because @code{error} is @code{#f}, and gives a list of sexps denoting +the status of services as its @code{result}. The @code{messages} field +is a possibly-empty list of strings meant to be displayed as is to the +user. + + +@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + +@node Others +@section Others + +@cindex hashes +@deffn {procedure} copy-hashq-table table new-size +Create a hash-table with size @var{new-size}, and insert all values +from @var{table} into it, using @code{eq?} when inserting. This +procedure is mainly used internally, but is a generally useful +utillity, so it can by used by everyone. +@end deffn + +@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + +@node Internals +@chapter Internals + +This chapter contains information about the design and the +implementation details of the Shepherd for people who want to hack it. + +The GNU@tie{}Shepherd is developed by a group of people in connection +with @uref{https://www.gnu.org/software/guix/, GuixSD}, GNU's advanced +distribution, but it can be used on other distros as well. You're very +much welcome to join us! You can report bugs to +@email{bug-guix@@gnu.org} and send patches or suggestions to +@email{guix-devel@@gnu.org}. + +@menu +* Coding standards:: How to properly hack the Shepherd. +* Design decisions:: Why the Shepherd is what it is. +* Service Internals:: How services actually work. +* Runlevel evolution:: Learning from past mistakes. +@end menu + +@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + +@node Coding standards +@section Coding standards + +About formatting: Use common sense and GNU Emacs (which actually is +the same, of course), and you almost can't get the formatting wrong. +Formatting should be as in Guile and Guix, basically. @xref{Coding +Style,,, guix, GNU Guix Reference Manual}, for more info. + +@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + +@node Design decisions +@section Design decisions + +@quotation Note +This section was written by Wolfgang J=C3=A4hrling back in 2003 and docu= ments +the original design of what was then known as GNU@tie{}dmd. The main +ideas remain valid but some implementation details and goals have +changed. +@end quotation + +The general idea of a service manager that uses dependencies, similar +to those of a Makefile, came from the developers of the GNU Hurd, but +as few people are satisfied with System V Init, many other people had +the same idea independently. Nevertheless, the Shepherd was written wit= h the +goal of becoming a replacement for System V Init on GNU/Hurd, which +was one of the reasons for choosing the extension language of the GNU +project, Guile, for implementation (another reason being that it makes +it just so much easier). + +The runlevel concept (i.e. thinking in @emph{groups} of services) is +sometimes useful, but often one also wants to operate on single +services. System V Init makes this hard: While you can start and stop +a service, @code{init} will not know about it, and use the runlevel +configuration as its source of information, opening the door for +inconsistencies (which fortunatly are not a practical problem +usually). In the Shepherd, this was avoided by having a central entity = that is +responsible for starting and stopping the services, which therefore +knows which services are actually started (if not completely +inproperly used, but that is a requirement which is impossible to +avoid anyway). While runlevels are not implemented yet, it is clear +that they will sit on top of the service concept, i.e. runlevels will +merely be an optional extension that the service concept does not rely +on. This also makes changes in the runlevel design easier when it may +become necessary. + +The consequence of having a daemon running that controls the services +is that we need another program as user interface which communicates +with the daemon. Fortunatly, this makes the commands necessary for +controlling services pretty short and intuitive, and gives the +additional bonus of adding some more flexibility. For example, it is +easiely possible to grant password-protected control over certain +services to unprivileged users, if desired. + +An essential aspect of the design of the Shepherd (which was already men= tioned +above) is that it should always know exactly what is happening, +i.e. which services are started and stopped. The alternative would +have been to not use a daemon, but to save the state on the file +system, again opening the door for inconsistencies of all sorts. +Also, we would have to use a seperate program for respawning a service +(which just starts the services, waits until it terminates and then +starts it again). Killing the program that does the respawning (but +not the service that is supposed to be respawned) would cause horrible +confusion. My understanding of ``The Right Thing'' is that this +conceptionally limited strategy is exactly what we do not want. + +The way dependencies work in the Shepherd took a while to mature, as it = was not +easy to figure out what is appropriate. I decided to not make it too +sophisticated by trying to guess what the user might want just to +theoretically fulfill the request we are processing. If something +goes wrong, it is usually better to tell the user about the problem +and let her fix it, taking care to make finding solutions or +workarounds for problems (like a misconfigured service) easy. This +way, the user is in control of what happens and we can keep the +implementation simple. To make a long story short, @emph{we don't try +to be too clever}, which is usually a good idea in developing +software. + +If you wonder why I was giving a ``misconfigured service'' as an +example above, consider the following situation, which actually is a +wonderful example for what was said in the previous paragraph: Service +X depends on symbol S, which is provided by both A and B. A depends +on AA, B depends on BB. AA and BB conflict with each other. The +configuration of A contains an error, which will prevent it from +starting; no service is running, but we want to start X now. In +resolving its dependencies, we first try to start A, which will cause +AA to be started. After this is done, the attempt of starting A +fails, so we go on to B, but its dependency BB will fail to start +because it conflicts with the running service AA. So we fail to +provide S, thus X cannot be started. There are several possibilities +to deal with this: + +@itemize @bullet +@item +When starting A fails, terminate those services which have been +started in order to fulfill its dependencies (directly and +indirectly). In case AA was running already, we would not want to +terminate it. Well, maybe we would, to avoid the conflict with BB. +But even if we would find out somehow that we need to terminate AA to +eventually start X, is the user aware of this and wants this to happen +(assuming AA was running already)? Probably not, she very likely has +assumed that starting A succeeds and thus terminating AA is not +necessary. Remember, unrelated (running) services might depend in AA. +Even if we ignore this issue, this strategy is not only complicated, +but also far from being perfect: Let's assume starting A succeeds, but +X also depends on a service Z, which requires BB. In that case, we +would need to detect in the first place that we should not even try to +start A, but directly satisfy X's dependency on S with B. + +@item +We could do it like stated above, but stop AA only if we know we won't +need it anymore (for resolving further dependencies), and start it +only when it does not conflict with anything that needs to get +started. But should we stop it if it conflicts with something that +@emph{might} get started? (We do not always know for sure what we +will start, as starting a service might fail and we want to fall back +to a service that also provides the particular required symbol in that +case.) I think that either decision will be bad in one case or +another, even if this solution is already horribly complicated. + +@item +When we are at it, we could just calculate a desired end-position, and +try to get there by starting (and stopping!) services, recalculating +what needs to be done whenever starting a service fails, also marking +that particular service as unstartable, except if it fails to start +because a dependency could not be resolved (or maybe even then?). +This is even more complicated. Instead of implementing this and +thereby producing code that (a) nobody understands, (b) certainly has +a lot of bugs, (c) will be unmaintainable and (d) causes users to +panic because they won't understand what will happen, I decided to do +the following instead: + +@item +Just report the error, and let the user fix it (in this case, fix the +configuration of A) or work around it (in this case, disable A so that +we won't start AA but directly go on to starting B). +@end itemize + +I hope you can agree that the latter solution after all is the best +one, because we can be sure to not do something that the user does not +want us to do. Software should not run amok. This explanation was +very long, but I think it was necessary to justify why the Shepherd uses= a very +primitive algorithm to resolve dependencies, despite the fact that it +could theoretically be a bit more clever in certain situations. + +One might argue that it is possible to ask the user if the planned +actions are ok with her, and if the plan changes ask again, but +especially given that services are supposed to usually work, I see few +reasons to make the source code of the Shepherd more complicated than +necessary. If you volunteer to write @emph{and} maintain a more +clever strategy (and volunteer to explain it to everyone who wants to +understand it), you are welcome to do so, of course@dots{} + +@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + +@node Service Internals +@section Service Internals + +@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + +@node Runlevel evolution +@section Runlevel evolution + +@quotation Note +This section was written by Wolfgang J=C3=A4hrling back in 2003 and is k= ept +mostly for historians to read. +@end quotation + +This section describes how the runlevel concept evolved over time. +This is basically a collection of mistakes, but is provided here for +your information, and possibly for your amusement, but I'm not sure if +all this weird dependency stuff is really that funny. + +@menu +* Runlevel assumptions:: What runlevels should be like +* Runlevels - part one:: The first attempts of making it work +* Runlevels - part two:: It should work... somehow... +@end menu + +@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + +@node Runlevel assumptions +@subsection Runlevel assumptions + +A runlevel is a system state, i.e. it consists of the information +about which services are supposed to be available and which not. This +vague definition implies that several different runlevel styles can be +implemented in a service manager. + +For example, you can do it like System V Init, specifying which +services should be started when we enter a runlevel and which ones +should be stopped when leaving it. But one could also specify for +every service in which runlevels it should be running. + +In the Shepherd, we do not want to limit ourselfes to a single runlevel = style. +We allow for all possible strategies to be implemented, providing the +most useful ones as defaults. We also want to make it possible to +combine the different styles arbitrariely. + +Therefore, when entering a runlevel, we call a user-defined piece of +code, passing it the list of currently active services and expecting +as the result a list of service symbols which tell us which services +we want to have running. This interface makes it very easy to +implement runlevel styles, but makes it not-so-easy for the runlevel +implementation itself, because we have to get from the current state +into a desired state, which might be more or less vague (since it is +not required to be a list of canonical names). Obviously service +conflicts and already running services need to be taken into account +when deciding which services should be used to provide the various +symbols. + +Also, the runlevel implementation should be implemented completely on +top of the service concept, i.e. the service part should not depend on +the idea of runlevels or care about them at all. Otherwise +understanding the service part (which is the most essential aspect of +the Shepherd) would become harder than necessary. + +@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + +@node Runlevels - part one +@subsection Runlevels, part one + +I came up with the following method (here in Pseudo-Scheme), which is +possibly slightly buggy, but should give you the idea: + +@lisp +;; Beginning with the canonical names in CURRENT-SERVICES, start and +;; stop services until getting into a state where everything requested +;; in TARGET-SERVICES (which does not only consist of canonical names) +;; is provided, and the things they depends on, but no more. +(define (switch-runlevel current-services target-services) + (let ((target-services-backup target-services) + (unstartable '())) + (let retry () + (repeat-until-none-of-these-changes-annythig + ;; Replace all of them with canonical names which provide them. + (canonicalize-names! target-services unstartable current-services= ) + ;; Add what we need additionally. + (add-dependencies! target-services unstartable current-services)) + (remove-redundancy! target-services) + (stop-all-unneeded target-services) + (catch 'service-could-not-be-started + (lambda () + ;; Iterate over the list, starting only those which + ;; have all dependencies already resolved, so nothing + ;; we don't want will be started. Repeat until done. + (carefully-start target-services)) + (lambda (key service) + (set! unstartable (cons service unstartable)) + (set! target-services backup-target-services) + (set! current-services (compute-current-services)) + (retry)))))) +@end lisp + +This indeed looks like a nice way to get what we want. However, the +details of this are not as easy as it looks like. When replacing +virtual services with canonical names, we have to be very careful. +Consider the following situation: + +The virtual service X is provided by both A and B, while Y is provided +only by B. We want to start C (which depends on X) and D (which +depends on Y). Obviously we should use B to fulfill the dependency +of C and D on X and Y, respectively. But when we see that we need +something that provides X, we are likely to do the wrong thing: Select +A. Thus, we need to clean this up later. I wanted to do this as +follows: + +While substituting virtual services with canonical names, we also safe +which one we selected to fulfill what, like this: + +@lisp +((A . (X)) + (B . (Y))) +@end lisp + +Later we look for conflicts, and as A and B conflict, we look which +one can be removed (things they provide but are not required by anyone +should be ignored, thus we need to create a list like the above). In +this case, we can replace A with B as B also provides X (but A does +not provide Y, thus the reverse is impossible). If both could be +used, we probably should decide which one to use by looking at further +conflicts, which gets pretty hairy. But, in this case, we are lucky +and end up with this: + +@lisp +((B . (X Y))) +@end lisp + +This way of finding out which service we should use in case of +conflicts sounds pretty sane, but if you think it will work well, you +have been fooled, because actually it breaks horribly in the following +situation: + +@multitable @columnfractions .10 .30 +@item Service @tab Provides +@item A @tab @code{W X Y -} +@item B @tab @code{W X - Z} +@item C @tab @code{- X Y Z} +@item D @tab @code{W - - -} +@end multitable + +If we need all of W, X, Y and Z, then obviously we need to take C and +D. But if we have a list like this, we cannot fix it: + +@lisp +((A . (W X Y)) + (B . (Z))) +@end lisp + +Thus, we cannot do it this way. + +@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + +@node Runlevels - part two +@subsection Runlevels, part two + +Let's look again at the table at the end of part two: + +@multitable @columnfractions .10 .30 +@item Service @tab Provides +@item A @tab @code{W X Y -} +@item B @tab @code{W X - Z} +@item C @tab @code{- X Y Z} +@item D @tab @code{W - - -} +@end multitable + +If from this table it is so obvious for us what we should do, then it +should also be possible to calculate it for a computer, given such a +table as input. Ok, we have to take into account conflicts that are +not visible in this table, but the general idea is usable. But how do +we find which combination works? I found only one way yet: Kind of a +brute force attack: Try combinations until we find one that works. + +This alone would be too slow. With 20 services we would have 2^20 +possible combinations, that is a bit more than a million. Fortunatly, +we can optimize this. First I thought we could remove all services +from the list that do not provide any symbol we need, but that is +obviously a stupid idea, as we might need them for dependencies, in +which case we need to take into account their conflicts. But the +following method would work: + +Very often a symbol that is required will be a canonical name already, +i.e. be provided only by a single service. Using our example above, +let's suppose we also need the symbol V, which is provided only by D. +The first step we do is to look which (required) symbols are provided +only by a single service, as we will need this service for sure. In +this case, we would need D. But by using it, we would also get the +other symbols it provides, W in this case. This means that we don't +need to bother looking at other services that provide W, as we cannot +use them because they conflict with a service that we definitely need. +In this case, we can remove A and B from the list this way. Note that +we can remove them entirely, as all their conflicts become irrelevant +to us now. In this simple case we would not even have to do much +else, C is the only remaining service. + +After this first step, there remain the symbols that are provided by +two or more services. In every combination we try, exactly one of +them must be used (and somehow we should take into account which +services are running already). This also reduces the amount of +possible combinations a lot. So what remains after that are the +services we might need for fulfilling dependencies. For them, we +could try all combinations (2^n), making sure that we always try +subsets before any of their supersets to avoid starting unneeded +services. We should take into account which services are already +running as well. + +The remaining question is, what to do if starting a service fails. A +simple solution would be to recursively remove all services that +depend on it directly or indirectly. That might cause undesired +side-effects, if a service was running but it had to be stopped +because one of the services that provides something it depends on gets +exchanged for another service that provides the same symbol, but fails +to start. The fact that we would have to stop the (first) service is +a problem on its own, though. + + +@c ********************************************************************* +@node GNU Free Documentation License +@appendix GNU Free Documentation License + +@include fdl-1.3.texi + +@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ + +@node Concept Index +@unnumbered Concept Index + +@printindex cp + +@node Procedure and Macro Index +@unnumbered Procedure and Macro Index + +@printindex fn + +@node Variable Index +@unnumbered Variable Index + +@printindex vr + +@node Type Index +@unnumbered Type Index + +@printindex tp + +@bye diff --git a/fdl-1.3.texi b/fdl-1.3.texi deleted file mode 100644 index cb71f05..0000000 --- a/fdl-1.3.texi +++ /dev/null @@ -1,505 +0,0 @@ -@c The GNU Free Documentation License. -@center Version 1.3, 3 November 2008 - -@c This file is intended to be included within another document, -@c hence no sectioning command or @node. - -@display -Copyright @copyright{} 2000, 2001, 2002, 2007, 2008 Free Software Founda= tion, Inc. -@uref{http://fsf.org/} - -Everyone is permitted to copy and distribute verbatim copies -of this license document, but changing it is not allowed. -@end display - -@enumerate 0 -@item -PREAMBLE - -The purpose of this License is to make a manual, textbook, or other -functional and useful document @dfn{free} in the sense of freedom: to -assure everyone the effective freedom to copy and redistribute it, -with or without modifying it, either commercially or noncommercially. -Secondarily, this License preserves for the author and publisher a way -to get credit for their work, while not being considered responsible -for modifications made by others. - -This License is a kind of ``copyleft'', which means that derivative -works of the document must themselves be free in the same sense. It -complements the GNU General Public License, which is a copyleft -license designed for free software. - -We have designed this License in order to use it for manuals for free -software, because free software needs free documentation: a free -program should come with manuals providing the same freedoms that the -software does. But this License is not limited to software manuals; -it can be used for any textual work, regardless of subject matter or -whether it is published as a printed book. We recommend this License -principally for works whose purpose is instruction or reference. - -@item -APPLICABILITY AND DEFINITIONS - -This License applies to any manual or other work, in any medium, that -contains a notice placed by the copyright holder saying it can be -distributed under the terms of this License. Such a notice grants a -world-wide, royalty-free license, unlimited in duration, to use that -work under the conditions stated herein. The ``Document'', below, -refers to any such manual or work. Any member of the public is a -licensee, and is addressed as ``you''. You accept the license if you -copy, modify or distribute the work in a way requiring permission -under copyright law. - -A ``Modified Version'' of the Document means any work containing the -Document or a portion of it, either copied verbatim, or with -modifications and/or translated into another language. - -A ``Secondary Section'' is a named appendix or a front-matter section -of the Document that deals exclusively with the relationship of the -publishers or authors of the Document to the Document's overall -subject (or to related matters) and contains nothing that could fall -directly within that overall subject. (Thus, if the Document is in -part a textbook of mathematics, a Secondary Section may not explain -any mathematics.) The relationship could be a matter of historical -connection with the subject or with related matters, or of legal, -commercial, philosophical, ethical or political position regarding -them. - -The ``Invariant Sections'' are certain Secondary Sections whose titles -are designated, as being those of Invariant Sections, in the notice -that says that the Document is released under this License. If a -section does not fit the above definition of Secondary then it is not -allowed to be designated as Invariant. The Document may contain zero -Invariant Sections. If the Document does not identify any Invariant -Sections then there are none. - -The ``Cover Texts'' are certain short passages of text that are listed, -as Front-Cover Texts or Back-Cover Texts, in the notice that says that -the Document is released under this License. A Front-Cover Text may -be at most 5 words, and a Back-Cover Text may be at most 25 words. - -A ``Transparent'' copy of the Document means a machine-readable copy, -represented in a format whose specification is available to the -general public, that is suitable for revising the document -straightforwardly with generic text editors or (for images composed of -pixels) generic paint programs or (for drawings) some widely available -drawing editor, and that is suitable for input to text formatters or -for automatic translation to a variety of formats suitable for input -to text formatters. A copy made in an otherwise Transparent file -format whose markup, or absence of markup, has been arranged to thwart -or discourage subsequent modification by readers is not Transparent. -An image format is not Transparent if used for any substantial amount -of text. A copy that is not ``Transparent'' is called ``Opaque''. - -Examples of suitable formats for Transparent copies include plain -ASCII without markup, Texinfo input format, La@TeX{} input -format, SGML or XML using a publicly available -DTD, and standard-conforming simple HTML, -PostScript or PDF designed for human modification. Examples -of transparent image formats include PNG, XCF and -JPG. Opaque formats include proprietary formats that can be -read and edited only by proprietary word processors, SGML or -XML for which the DTD and/or processing tools are -not generally available, and the machine-generated HTML, -PostScript or PDF produced by some word processors for -output purposes only. - -The ``Title Page'' means, for a printed book, the title page itself, -plus such following pages as are needed to hold, legibly, the material -this License requires to appear in the title page. For works in -formats which do not have any title page as such, ``Title Page'' means -the text near the most prominent appearance of the work's title, -preceding the beginning of the body of the text. - -The ``publisher'' means any person or entity that distributes copies -of the Document to the public. - -A section ``Entitled XYZ'' means a named subunit of the Document whose -title either is precisely XYZ or contains XYZ in parentheses following -text that translates XYZ in another language. (Here XYZ stands for a -specific section name mentioned below, such as ``Acknowledgements'', -``Dedications'', ``Endorsements'', or ``History''.) To ``Preserve the T= itle'' -of such a section when you modify the Document means that it remains a -section ``Entitled XYZ'' according to this definition. - -The Document may include Warranty Disclaimers next to the notice which -states that this License applies to the Document. These Warranty -Disclaimers are considered to be included by reference in this -License, but only as regards disclaiming warranties: any other -implication that these Warranty Disclaimers may have is void and has -no effect on the meaning of this License. - -@item -VERBATIM COPYING - -You may copy and distribute the Document in any medium, either -commercially or noncommercially, provided that this License, the -copyright notices, and the license notice saying this License applies -to the Document are reproduced in all copies, and that you add no other -conditions whatsoever to those of this License. You may not use -technical measures to obstruct or control the reading or further -copying of the copies you make or distribute. However, you may accept -compensation in exchange for copies. If you distribute a large enough -number of copies you must also follow the conditions in section 3. - -You may also lend copies, under the same conditions stated above, and -you may publicly display copies. - -@item -COPYING IN QUANTITY - -If you publish printed copies (or copies in media that commonly have -printed covers) of the Document, numbering more than 100, and the -Document's license notice requires Cover Texts, you must enclose the -copies in covers that carry, clearly and legibly, all these Cover -Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on -the back cover. Both covers must also clearly and legibly identify -you as the publisher of these copies. The front cover must present -the full title with all words of the title equally prominent and -visible. You may add other material on the covers in addition. -Copying with changes limited to the covers, as long as they preserve -the title of the Document and satisfy these conditions, can be treated -as verbatim copying in other respects. - -If the required texts for either cover are too voluminous to fit -legibly, you should put the first ones listed (as many as fit -reasonably) on the actual cover, and continue the rest onto adjacent -pages. - -If you publish or distribute Opaque copies of the Document numbering -more than 100, you must either include a machine-readable Transparent -copy along with each Opaque copy, or state in or with each Opaque copy -a computer-network location from which the general network-using -public has access to download using public-standard network protocols -a complete Transparent copy of the Document, free of added material. -If you use the latter option, you must take reasonably prudent steps, -when you begin distribution of Opaque copies in quantity, to ensure -that this Transparent copy will remain thus accessible at the stated -location until at least one year after the last time you distribute an -Opaque copy (directly or through your agents or retailers) of that -edition to the public. - -It is requested, but not required, that you contact the authors of the -Document well before redistributing any large number of copies, to give -them a chance to provide you with an updated version of the Document. - -@item -MODIFICATIONS - -You may copy and distribute a Modified Version of the Document under -the conditions of sections 2 and 3 above, provided that you release -the Modified Version under precisely this License, with the Modified -Version filling the role of the Document, thus licensing distribution -and modification of the Modified Version to whoever possesses a copy -of it. In addition, you must do these things in the Modified Version: - -@enumerate A -@item -Use in the Title Page (and on the covers, if any) a title distinct -from that of the Document, and from those of previous versions -(which should, if there were any, be listed in the History section -of the Document). You may use the same title as a previous version -if the original publisher of that version gives permission. - -@item -List on the Title Page, as authors, one or more persons or entities -responsible for authorship of the modifications in the Modified -Version, together with at least five of the principal authors of the -Document (all of its principal authors, if it has fewer than five), -unless they release you from this requirement. - -@item -State on the Title page the name of the publisher of the -Modified Version, as the publisher. - -@item -Preserve all the copyright notices of the Document. - -@item -Add an appropriate copyright notice for your modifications -adjacent to the other copyright notices. - -@item -Include, immediately after the copyright notices, a license notice -giving the public permission to use the Modified Version under the -terms of this License, in the form shown in the Addendum below. - -@item -Preserve in that license notice the full lists of Invariant Sections -and required Cover Texts given in the Document's license notice. - -@item -Include an unaltered copy of this License. - -@item -Preserve the section Entitled ``History'', Preserve its Title, and add -to it an item stating at least the title, year, new authors, and -publisher of the Modified Version as given on the Title Page. If -there is no section Entitled ``History'' in the Document, create one -stating the title, year, authors, and publisher of the Document as -given on its Title Page, then add an item describing the Modified -Version as stated in the previous sentence. - -@item -Preserve the network location, if any, given in the Document for -public access to a Transparent copy of the Document, and likewise -the network locations given in the Document for previous versions -it was based on. These may be placed in the ``History'' section. -You may omit a network location for a work that was published at -least four years before the Document itself, or if the original -publisher of the version it refers to gives permission. - -@item -For any section Entitled ``Acknowledgements'' or ``Dedications'', Preser= ve -the Title of the section, and preserve in the section all the -substance and tone of each of the contributor acknowledgements and/or -dedications given therein. - -@item -Preserve all the Invariant Sections of the Document, -unaltered in their text and in their titles. Section numbers -or the equivalent are not considered part of the section titles. - -@item -Delete any section Entitled ``Endorsements''. Such a section -may not be included in the Modified Version. - -@item -Do not retitle any existing section to be Entitled ``Endorsements'' or -to conflict in title with any Invariant Section. - -@item -Preserve any Warranty Disclaimers. -@end enumerate - -If the Modified Version includes new front-matter sections or -appendices that qualify as Secondary Sections and contain no material -copied from the Document, you may at your option designate some or all -of these sections as invariant. To do this, add their titles to the -list of Invariant Sections in the Modified Version's license notice. -These titles must be distinct from any other section titles. - -You may add a section Entitled ``Endorsements'', provided it contains -nothing but endorsements of your Modified Version by various -parties---for example, statements of peer review or that the text has -been approved by an organization as the authoritative definition of a -standard. - -You may add a passage of up to five words as a Front-Cover Text, and a -passage of up to 25 words as a Back-Cover Text, to the end of the list -of Cover Texts in the Modified Version. Only one passage of -Front-Cover Text and one of Back-Cover Text may be added by (or -through arrangements made by) any one entity. If the Document already -includes a cover text for the same cover, previously added by you or -by arrangement made by the same entity you are acting on behalf of, -you may not add another; but you may replace the old one, on explicit -permission from the previous publisher that added the old one. - -The author(s) and publisher(s) of the Document do not by this License -give permission to use their names for publicity for or to assert or -imply endorsement of any Modified Version. - -@item -COMBINING DOCUMENTS - -You may combine the Document with other documents released under this -License, under the terms defined in section 4 above for modified -versions, provided that you include in the combination all of the -Invariant Sections of all of the original documents, unmodified, and -list them all as Invariant Sections of your combined work in its -license notice, and that you preserve all their Warranty Disclaimers. - -The combined work need only contain one copy of this License, and -multiple identical Invariant Sections may be replaced with a single -copy. If there are multiple Invariant Sections with the same name but -different contents, make the title of each such section unique by -adding at the end of it, in parentheses, the name of the original -author or publisher of that section if known, or else a unique number. -Make the same adjustment to the section titles in the list of -Invariant Sections in the license notice of the combined work. - -In the combination, you must combine any sections Entitled ``History'' -in the various original documents, forming one section Entitled -``History''; likewise combine any sections Entitled ``Acknowledgements''= , -and any sections Entitled ``Dedications''. You must delete all -sections Entitled ``Endorsements.'' - -@item -COLLECTIONS OF DOCUMENTS - -You may make a collection consisting of the Document and other documents -released under this License, and replace the individual copies of this -License in the various documents with a single copy that is included in -the collection, provided that you follow the rules of this License for -verbatim copying of each of the documents in all other respects. - -You may extract a single document from such a collection, and distribute -it individually under this License, provided you insert a copy of this -License into the extracted document, and follow this License in all -other respects regarding verbatim copying of that document. - -@item -AGGREGATION WITH INDEPENDENT WORKS - -A compilation of the Document or its derivatives with other separate -and independent documents or works, in or on a volume of a storage or -distribution medium, is called an ``aggregate'' if the copyright -resulting from the compilation is not used to limit the legal rights -of the compilation's users beyond what the individual works permit. -When the Document is included in an aggregate, this License does not -apply to the other works in the aggregate which are not themselves -derivative works of the Document. - -If the Cover Text requirement of section 3 is applicable to these -copies of the Document, then if the Document is less than one half of -the entire aggregate, the Document's Cover Texts may be placed on -covers that bracket the Document within the aggregate, or the -electronic equivalent of covers if the Document is in electronic form. -Otherwise they must appear on printed covers that bracket the whole -aggregate. - -@item -TRANSLATION - -Translation is considered a kind of modification, so you may -distribute translations of the Document under the terms of section 4. -Replacing Invariant Sections with translations requires special -permission from their copyright holders, but you may include -translations of some or all Invariant Sections in addition to the -original versions of these Invariant Sections. You may include a -translation of this License, and all the license notices in the -Document, and any Warranty Disclaimers, provided that you also include -the original English version of this License and the original versions -of those notices and disclaimers. In case of a disagreement between -the translation and the original version of this License or a notice -or disclaimer, the original version will prevail. - -If a section in the Document is Entitled ``Acknowledgements'', -``Dedications'', or ``History'', the requirement (section 4) to Preserve -its Title (section 1) will typically require changing the actual -title. - -@item -TERMINATION - -You may not copy, modify, sublicense, or distribute the Document -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense, or distribute it is void, and -will automatically terminate your rights under this License. - -However, if you cease all violation of this License, then your license -from a particular copyright holder is reinstated (a) provisionally, -unless and until the copyright holder explicitly and finally -terminates your license, and (b) permanently, if the copyright holder -fails to notify you of the violation by some reasonable means prior to -60 days after the cessation. - -Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - -Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, receipt of a copy of some or all of the same material does -not give you any rights to use it. - -@item -FUTURE REVISIONS OF THIS LICENSE - -The Free Software Foundation may publish new, revised versions -of the GNU Free Documentation License from time to time. Such new -versions will be similar in spirit to the present version, but may -differ in detail to address new problems or concerns. See -@uref{http://www.gnu.org/copyleft/}. - -Each version of the License is given a distinguishing version number. -If the Document specifies that a particular numbered version of this -License ``or any later version'' applies to it, you have the option of -following the terms and conditions either of that specified version or -of any later version that has been published (not as a draft) by the -Free Software Foundation. If the Document does not specify a version -number of this License, you may choose any version ever published (not -as a draft) by the Free Software Foundation. If the Document -specifies that a proxy can decide which future versions of this -License can be used, that proxy's public statement of acceptance of a -version permanently authorizes you to choose that version for the -Document. - -@item -RELICENSING - -``Massive Multiauthor Collaboration Site'' (or ``MMC Site'') means any -World Wide Web server that publishes copyrightable works and also -provides prominent facilities for anybody to edit those works. A -public wiki that anybody can edit is an example of such a server. A -``Massive Multiauthor Collaboration'' (or ``MMC'') contained in the -site means any set of copyrightable works thus published on the MMC -site. - -``CC-BY-SA'' means the Creative Commons Attribution-Share Alike 3.0 -license published by Creative Commons Corporation, a not-for-profit -corporation with a principal place of business in San Francisco, -California, as well as future copyleft versions of that license -published by that same organization. - -``Incorporate'' means to publish or republish a Document, in whole or -in part, as part of another Document. - -An MMC is ``eligible for relicensing'' if it is licensed under this -License, and if all works that were first published under this License -somewhere other than this MMC, and subsequently incorporated in whole -or in part into the MMC, (1) had no cover texts or invariant sections, -and (2) were thus incorporated prior to November 1, 2008. - -The operator of an MMC Site may republish an MMC contained in the site -under CC-BY-SA on the same site at any time before August 1, 2009, -provided the MMC is eligible for relicensing. - -@end enumerate - -@page -@heading ADDENDUM: How to use this License for your documents - -To use this License in a document you have written, include a copy of -the License in the document and put the following copyright and -license notices just after the title page: - -@smallexample -@group - Copyright (C) @var{year} @var{your name}. - Permission is granted to copy, distribute and/or modify this document - under the terms of the GNU Free Documentation License, Version 1.3 - or any later version published by the Free Software Foundation; - with no Invariant Sections, no Front-Cover Texts, and no Back-Cover - Texts. A copy of the license is included in the section entitled ``GN= U - Free Documentation License''. -@end group -@end smallexample - -If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, -replace the ``with@dots{}Texts.''@: line with this: - -@smallexample -@group - with the Invariant Sections being @var{list their titles}, with - the Front-Cover Texts being @var{list}, and with the Back-Cover Text= s - being @var{list}. -@end group -@end smallexample - -If you have Invariant Sections without Cover Texts, or some other -combination of the three, merge those two alternatives to suit the -situation. - -If your document contains nontrivial examples of program code, we -recommend releasing these examples in parallel under your choice of -free software license, such as the GNU General Public License, -to permit their use in free software. - -@c Local Variables: -@c ispell-local-pdict: "ispell-dict" -@c End: diff --git a/shepherd.texi b/shepherd.texi deleted file mode 100644 index 5dc5f9c..0000000 --- a/shepherd.texi +++ /dev/null @@ -1,1593 +0,0 @@ -\input texinfo @c -*- texinfo -*- -@c shepherd.texi -- The documentation in Texinfo format. -@documentencoding UTF-8 -@setfilename shepherd.info -@settitle The GNU Shepherd Manual - -@include version.texi -@set OLD-YEARS 2002, 2003 -@set NEW-YEARS 2013, 2016 - -@copying -Copyright @copyright{} @value{OLD-YEARS} Wolfgang J@"ahrling@* -Copyright @copyright{} @value{NEW-YEARS} Ludovic Court=C3=A8s - -Permission is granted to copy, distribute and/or modify this document -under the terms of the GNU Free Documentation License, Version 1.3 or -any later version published by the Free Software Foundation; with no -Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. A -copy of the license is included in the section entitled ``GNU Free -Documentation License''. -@end copying - -@dircategory System software -@direntry -* shepherd: (shepherd). The Shepherd service manager. -* herd: (shepherd)Invoking herd - Controlling the Shepherd service manager. -* reboot: (shepherd)Invoking reboot - Rebooting a Shepherd-controlled system. -* halt: (shepherd)Invoking halt - Turning off a Shepherd-controlled system. -@end direntry - -@titlepage -@title The GNU Shepherd Manual -@subtitle For use with the GNU Shepherd @value{VERSION} -@subtitle Last updated @value{UPDATED} - -@author Wolfgang J@"ahrling -@author Ludovic Court=C3=A8s - -@insertcopying -@end titlepage - -@contents - - -@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -@ifnottex -@node Top -@top The GNU Shepherd Manual - -This manual documents the GNU@tie{}Shepherd version @value{VERSION}, a -service manager for the GNU system. - -@menu -* Introduction:: Introduction to the Shepherd service manager. -* Jump Start:: How to do simple things with the Shepherd. -* herd and shepherd:: User interface to service management. -* Services:: Details on services. -* Runlevels:: Details on runlevels. -* Misc Facilities:: Generally useful things provided by the Shepherd. -* Internals:: Hacking shepherd. - -* GNU Free Documentation License:: The license of this manual. -* Concept Index:: -* Procedure and Macro Index:: -* Variable Index:: -* Type Index:: -@end menu -@end ifnottex - -@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -@node Introduction -@chapter Introduction - -@cindex service manager -This manual documents the GNU@tie{}Daemon Shepherd, or GNU@tie{}Shepherd -for short. The Shepherd looks after system services, typically @dfn{dae= mons}. -It is used to start and stop them in a reliable -fashion. For instance it will dynamically determine and start any -other services that our desired service depends upon. As another -example, the Shepherd might detect conflicts among services. In this -situation it would simply prevent the conflicting services from -running concurrently. - -The Shepherd is the @dfn{init system} of the GNU operating system---it i= s the -first user process that gets started, typically with PID 1, and runs -as @code{root}. Normally the purpose of init systems is to manage all -system-wide services, but the Shepherd can also be a useful tool assisti= ng -unprivileged users in the management of their own daemons. - -Flexible software requires some time to master and -the Shepherd is no different. But don't worry: this manual should allow= you to -get started quickly. Its first chapter is designed as a practical -introduction to the Shepherd and should be all you need for everyday use -(@pxref{Jump Start}). In chapter two we will describe the -@command{herd} and @command{shepherd} programs, and their relationship, = in -more detail (@ref{herd and shepherd}). Subsequent chapters provide a fu= ll -reference manual and plenty of examples, covering all of Shepherd's -capabilities. Finally, the last chapter provides information for -those souls brave enough to hack the Shepherd itself. - -@cindex dmd -The Shepherd was formerly known as ``dmd'', which stands for @dfn{Daemon -Managing Daemons} (or @dfn{Daemons-Managing Daemon}?). - -@cindex Guile -@cindex Scheme -@cindex GOOPS -This program is written in Guile, an implementation of the -Scheme programming language, using the GOOPS extension for -object-orientation. Guile is also the Shepherd's configuration language= . -@xref{Introduction,,, guile, GNU Guile Reference Manual}, for an -introduction to Guile. We have tried to -make the Shepherd's basic features as accessible as possible---you shoul= d be -able to use these even if you do not know how to program in Scheme. A -basic grasp of Guile and GOOPS is required only if you wish to make -use of the Shepherd's more advanced features. - -@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -@node Jump Start -@chapter Jump Start - -@cindex prefix -This chapter gives a short overview of the Shepherd. It is enough if yo= u just -need the basic features of it. As it is not assumed that readers are -familiar with all the involved issues, a very experienced user might -be annoyed by the often very detailed descriptions in this -introduction. Those users are encouraged to just skip to the -reference section. - -Note that all the full file names in the following text are based on -the assumption that you have installed the Shepherd with an empty prefix= . If -your the Shepherd installation for example resides in @code{/usr/local} -instead, add this directory name in front of the absolute file names -mentioned below. - -@cindex Configuration file -When @command{shepherd} gets started, it reads and evaluates a -configuration file. When it is started with superuser priviledges, it -tries to use @code{/etc/shepherd.scm}. When started as normal user, it -looks for a file called @code{$XDG_CONFIG_HOME/shepherd/init.scm}. If -the @code{XDG_CONFIG_HOME} environment variable is not defined, -@code{$HOME/.config/shepherd/init.scm} is used instead. With the option -@code{--config} (or, for short, @code{-c}), you can specify where to -look instead. So if you want to start @command{shepherd} with an -alternative file, use one of the following commands: - -@example -shepherd --config=3D/etc/shepherd.scm.old -shepherd -c /etc/shepherd.scm.old -@end example - -@cindex Starting a service -As the final ``d'' suggests, @command{shepherd} is just -a daemon that (usually) runs in the -background, so you will not interact with it directly. After it is -started, @command{shepherd} will listen on a socket special file, usuall= y -@code{/var/run/shepherd/socket}, for further commands. You use the tool -@dfn{herd} to send these commands to @command{shepherd}. Usage of herd = is simple and -straightforward: To start a service called @code{apache}, you use: - -@example -herd start apache -@end example - -@cindex Status (of services) -@cindex Service status -When you do this, all its dependencies will get resolved. For -example, a webserver is quite likely to depend on working networking, -thus it will depend on a service called @code{networking}. So if you -want to start @code{apache}, and @code{networking} is not yet running, i= t -will automatically be started as well. The current status of all the -services defined in the configuration file can be queried like this: - -@example -herd status -@end example - -@noindent -Or, to get additional details about each service, run: - -@example -herd detailed-status -@end example - -@noindent -In this example, this would show the @code{networking} and @code{apache} -services as started. If you just want to know the status of the -@code{apache} service, run: - -@example -herd status apache -@end example - -@cindex Stopping a service -You can stop -a service and all the services that depend on it will be stopped. -Using the example above, if you stop @code{networking}, the service -@code{apache} will be stopped as well---which makes perfect sense, -as it cannot work without the network being up. To actually stop a -service, you use the following, probably not very surprising, command: - -@example -herd stop networking -@end example - -There are two more actions you can perform on every service: The -actions @code{enable} and @code{disable} are used to prevent and allow -starting of the particular service. If a service is intended to be -restarted whenever it terminates (how this can be done will not be -covered in this introduction), but it is respawning too often in a -short period of time (by default 5 times in 5 seconds), it will -automatically be disabled. After you have fixed the problem that -caused it from being respawned too fast, you can start it again with -the commands: - -@example -herd enable foo -herd start foo -@end example - -@cindex virtual services -@cindex fallback services -But there is far more you can do than just that. Services can not -only simply depend on other services, they can also depend on -@emph{virtual} services. A virtual service is a service that is -provided by one or more service additionally. For instance, a service -called @code{exim} might provide the virtual service -@code{mailer-daemon}. That could as well be provided by a service -called @code{smail}, as both are mailer-daemons. If a service needs -any mailer-daemon, no matter which one, it can just depend on -@code{mailer-daemon}, and one of those who provide it gets started (if -none is running yet) when resolving dependencies. The nice thing is -that, if trying to start one of them fails, @command{shepherd} will go o= n and try to -start the next one, so you can also use virtual services for -specifying @emph{fallbacks}. - -Additionally to all that, you can perform service-specific actions. -Coming back to our original example, @code{apache} is able to -reload its modules, therefore the action @code{reload-modules} might -be available: - -@example -herd reload-modules apache -@end example - -The service-specific actions can only be used when the service is -started, i.e. the only thing you can do to a stopped service is -starting it. An exception exists, see below. (If you may at some -point find this too restrictive because you want to use variants of -the same service which are started in different ways, consider using -different services for those variants instead, which all provide the -same virtual service and thus conflict with each other, if this is -desired. That's one of the reasons why virtual services exist, after -all.) - -There are two actions which are special, because even if services -can implement them on their own, a default implementation is provided -by @command{shepherd} (another reason why they are special is that the d= efault -implementations can be called even when the service is not running; -this inconsistency is just to make it more intuitive to get -information about the status of a service, see below). - -These actions are @code{restart} and @code{status}. The default -implementation of @code{restart} calls @code{stop} and @code{start} on -the affected service in order, the @code{status} action displays some -general information about the service, like what it provides, what it -depends on and with which other services it conflicts (because they -provide a virtual service that is also provided by that particular -service). - -Another special action is @code{list-actions}, which displays a list -of the additional actions a service provides; obviously, it can also -be called when the service is not running. Services cannot provide -their own implementation of @code{list-actions}. - -A special service is @code{root}, which is used for controlling the -Shepherd itself. You can also reference to this service as -@code{shepherd}. It implements various actions. For example, the -@code{status} action displays which services are started and which ones -are stopped, whereas @code{detailed-status} has the effect of applying -the default implementation of @code{status} to all services one after -another. The @code{load} action is unusual insofar as it shows a -feature that is actually available to all services, but which we have -not seen yet: It takes an additional argument. You can use @code{load} -to load arbitrary code into the Shepherd at runtime, like this: - -@example -herd load shepherd ~/additional-services.scm -@end example - -This is enough now about the @command{herd} and @command{shepherd} progr= ams, we -will now take a look at how to configure the Shepherd. In the configura= tion -file, we need mainly the definition of services. We can also do -various other things there, like starting a few services already. - -FIXME: Finish. For now, look at the @code{examples/} subdirectory. - -@example -... -@end example - -Ok, to summarize: - -@itemize @bullet -@item -@command{shepherd} is a daemon, @command{herd} the program that controls= it. -@item -You can start, stop, restart, enable and disable every service, as -well as display its status. -@item -You can perform additional service-specific actions, which you can -also list. -@item -Actions can have arguments. -@item -You can display the status of a service, even if the service does not -provide a specific implementation for this action. The same is true -for restarting. -@item -The @code{root}/@code{shepherd} service is used to control -@command{shepherd} itself. -@end itemize - -@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -@node herd and shepherd -@chapter @command{herd} and @command{shepherd} - -@cindex herd -@cindex shepherd -@cindex daemon -@cindex daemon controller -@cindex relative file names -@cindex herding, of daemons -The daemon that runs in the background and is responsible for -controlling the services is @command{shepherd}, while the user interface -tool is called @command{herd}: it's the command that allows you to -actually @emph{herd} your daemons@footnote{ -@cindex deco, daemon controller -In the past, when the -GNU@tie{}Shepherd was known as GNU@tie{}dmd, the @command{herd} command -was called @code{deco}, for @dfn{DaEmon COntroller}.}. To perform an -action, like stopping a service or calling an action of a service, you -use the herd program. It will communicate with shepherd over a Unix -Domain Socket. - -Thus, you start @command{shepherd} once, and then always use herd whenev= er you want -to do something service-related. Since herd passes its current -working directory to @command{shepherd}, you can pass relative file name= s without -trouble. Both @command{shepherd} and herd understand the standard argum= ents -@code{--help}, @code{--version} and @code{--usage}. - - -@menu -* Invoking shepherd:: How to start the service damon. -* Invoking herd:: Controlling daemons. -* Invoking reboot:: Rebooting a shepherd-controlled system. -* Invoking halt:: Turning off a shepherd-controlled system= . -@end menu - -@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -@node Invoking shepherd -@section Invoking @command{shepherd} - -@cindex @command{shepherd} Invocation -@cindex invoking @command{shepherd} -The @code{shepherd} program has the following synopsis: - -@example -shepherd [@var{option}@dots{}] -@end example - -It accepts the following options: - -@table @samp -@item -c @var{file} -@itemx --config=3D@var{file} -Read and evaluate @var{file} as the configuration script on startup. - -@var{file} is evaluated in the context of a fresh module where bindings -from the @code{(shepherd service)} module and Guile's @code{(oop goops)}= are -available, in addition to the default set of Guile bindings. In -particular, this means that code in @var{file} may use -@code{register-services}, the @code{} class, and related tools -(@pxref{Services}). - -@item -I -@itemx --insecure -@cindex security -@cindex insecure -Do not check if the directory where the socket---our communication -rendez-vous with @command{herd}---is located has permissions @code{700}. -If this option is not specified, @command{shepherd} will abort if the -permissions are not as expected. - -@item -l [@var{file}] -@itemx --logfile[=3D@var{file}] -@cindex logging -@cindex log file -Log output into @var{file}, or if @var{file} is not given, -@code{/var/log/shepherd.log} when running as superuser, -@code{$XDG_CONFIG_HOME/shepherd/shepherd.log} otherwise. - -@item --pid[=3D@var{file}] -When @command{shepherd} is ready to accept connections, write its PID to= @var{file} or -to the standard output if @var{file} is omitted. - -@item -p [@var{file}] -@itemx --persistency[=3D@var{file}] -@c FIXME-CRITICAL - -@item -s @var{file} -@itemx --socket=3D@var{file} -@cindex socket special file -Receive further commands on the socket special file @var{file}. If -this option is not specified, @file{@var{localstatedir}/run/shepherd/soc= ket} is -taken. - -If @code{-} is specified as file name, commands will be read from -standard input, one per line, as would be passed on a @command{herd} -command line (@pxref{Invoking herd}). - -@item --quiet -Synonym for @code{--silent}. - -@end table - -@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -@node Invoking herd -@section Invoking herd - -@cindex herd -The @command{herd} command is a generic client program to control a -running instance of @command{shepherd} (@pxref{Invoking shepherd}). It = has the -following synopsis: - -@example -herd [@var{option}@dots{}] @var{action} [@var{service} [@var{arg}@dots{}= ]] -@end example - -It causes the @var{action} of the @var{service} to be invoked. When -@var{service} is omitted and @var{action} is @code{status} or -@code{detailed-status}, the @code{root} service is used@footnote{This -shorthand does not work for other actions such as @code{stop}, because -inadvertently typing @code{herd stop} would stop all the services, which -could be pretty annoying.} (@pxref{The root and unknown services}, for -more information on the @code{root} service.) - -For each action, you should pass the appropriate @var{arg}s. Actions -that are available for every service are @code{start}, @code{stop}, -@code{restart}, @code{status}, @code{enable}, @code{disable}, and -@code{doc}. - -If you pass a file name as an @var{arg}, it will be passed as-is to -the Shepherd, thus if it is not an absolute name, it is local to the cur= rent -working directory of @command{shepherd}, not to herd. - -The @code{herd} command understands the following option: - -@table @samp - -@item -s @var{file} -@itemx --socket=3D@var{file} -Send commands to the socket special file @var{file}. If this option is -not specified, @file{@var{localstatedir}/run/shepherd/socket} is taken. - -@end table - -The @code{herd} command returns zero on success, and a non-zero exit -code on failure. In particular, it returns a non-zero exit code when -@var{action} or @var{service} does not exist and when the given action -failed. - - -@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -@node Invoking reboot -@section Invoking reboot - -@cindex herd -The @command{reboot} command is a convenience client program to instruct -the Shepherd (when used as an init system) to stop all running services = and -reboot the system. It has the following synopsis: - -@example -reboot [@var{option}@dots{}] -@end example - -It is equivalent to running @command{herd stop shepherd}. The -@code{reboot} command understands the following option: - -@table @samp - -@item -s @var{file} -@itemx --socket=3D@var{file} -Send commands to the socket special file @var{file}. If this option is -not specified, @file{@var{localstatedir}/run/shepherd/socket} is taken. - -@end table - -@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -@node Invoking halt -@section Invoking halt - -@cindex herd -The @command{halt} command is a convenience client program to instruct -the Shepherd (when used as an init system) to stop all running services = and turn -off the system. It has the following synopsis: - -@example -halt [@var{option}@dots{}] -@end example - -It is equivalent to running @command{herd power-off shepherd}. As -usual, the @code{halt} command understands the following option: - -@table @samp - -@item -s @var{file} -@itemx --socket=3D@var{file} -Send commands to the socket special file @var{file}. If this option is -not specified, @file{@var{localstatedir}/run/shepherd/socket} is taken. - -@end table - - -@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -@node Services -@chapter Services - -@cindex service -@tindex -The @dfn{service} is obviously a very important concept of the Shepherd.= On the -Guile level, a service is represented as an instance of -@code{}, a GOOPS class (@pxref{GOOPS,,, guile, GNU Guile -Reference Manual}). When creating an instance of it, you can specify -the initial values of its slots, and you actually must do this for some -of the slots. - -The @code{} class and its associated procedures and methods are -defined in the @code{(shepherd service)} module. - -@menu -* Slots of services:: What a object consists of. -* Methods of services:: What you can do with a object= . -* Service Convenience:: How to conveniently work with services. -* Service De- and Constructors:: Commonly used ways of starting and - stopping services. -* Service Examples:: Examples that show how services are use= d. -* The root and unknown services:: Special services in the Shepherd. -@end menu - -@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -@node Slots of services -@section Slots of services - -@cindex , slots of -@cindex slots of -A service has the following slots, all of which can be initialized -with a keyword (i.e. @code{#:provides}, used when creating the object) -of the same name, except where stated otherwise. You should not -access them directly with @code{slot-ref} or @code{slot-set!} -usually, use the methods of the service class @ref{Methods of -services} instead. - -@itemize @bullet -@item -@vindex provides (slot of ) -@cindex canonical names of services -@code{provides} is a list of symbols that are provided by the service. -A symbol can only be provided by one service running at a time, -i.e. if two services provide the same symbol, only one of them can -run, starting the other one will fail. Therefore, these symbols are -mainly used to denote conflicting services. The first symbol in the -list is the canonical name for the service, thus it must be unique. -This slot has no default value and must therefore be initialized. - -@item -@vindex requires (slot of ) -@code{requires} is, like @code{provides}, a list of symbols that -specify services. In this case, they name what this service depends -on, i.e. before the service can be started, services that provide -those symbols must be started. If a required symbol is provided by -several services, one will be started. By default, this slot -contains the empty list. - -@item -@vindex running (slot of ) -@cindex Hook for individual services -@code{running} is a hook that can be used by each service in its own -way. The default value is @code{#f}, which indicates that the service -is not running. When an attempt is made to start the service, it will -be set to the return value of the procedure in the @code{start} slot. -It will also be passed as an argument to the procedure in the -@code{stop} slot. This slot can not be initialized with a keyword. - -@item -@vindex respawn? (slot of ) -@cindex Respawning services -@code{respawn?} specifies whether the service should be respawned by -the Shepherd. If this slot has the value @code{#t}, then assume the -@code{running} slot specifies a child process PID and restart the -service if that process terminates. Otherwise this slot is @code{#f}, -which is the default. See also the @code{last-respawns} slot. - -@item -@vindex start (slot of ) -@cindex Starting a service -@cindex Service constructor -@code{start} contains the ``constructor'' for the service, which will -be called to start the service. (Therefore, it is not a constructor -in the sense that it initializes the slots of a @code{} -object.) This must be a procedure that accepts any amount of -arguments, which will be the additional arguments supplied by the -user. If the starting attempt failed, it must return @code{#f}. The -value will be stored in the @code{running} slot. The default value is -a procedure that returns @code{#t} and performs no further actions, -therefore it is desirable to specify a different one usually. - -@item -@vindex stop (slot of ) -@cindex Stoping a service -@cindex Service destructor -@code{stop} is, similar to @code{start}, a slot containing a -procedure. But in this case, it gets the current value of the -@code{running} slot as first argument and the user-supplied arguments -as further arguments; it gets called to stop the service. Its return -value will again be stored in the @code{running} slot, so that it -should return @code{#f} if it is now possible again to start the -service at a later point. The default value is a procedure that -returns @code{#f} and performs no further actions. - -@item -@vindex actions (slot of ) -@cindex Actions of services -@cindex Service actions -@code{actions} specifies the additional actions that can be performed -on a service when it is running. A typical example for this is the -@code{restart} action. The macro @code{make-actions} @ref{Service -Convenience} is provided to abstract the actual data representation -format for this slot. (It actually is a hash currently.) - -@item -@vindex enabled? (slot of ) -@code{enabled?} cannot be initialized with a keyword, and contains -@code{#t} by default. When the value becomes @code{#f} at some point, -this will prevent the service from getting started. A service can be -enabled and disabled with the methods @code{enable} and -@code{disable}, respectively @ref{Methods of services}. - -@item -@vindex last-respawns (slot of ) -@code{last-respawns} cannot be initialized with a keyword and is only -ever used when the @code{respawn?} slot contains @code{#t}; it is a -circular list with @code{(car respawn-limit)} elements, where each -element contains the time when it was restarted, initially all 0, -later a time in seconds since the Epoch. The first element is the one -that contains the oldest one, the last one the newest. - -@item -@vindex stop-delay? (slot of ) -@code{stop-delay?} being false causes the @code{stop} slot to be -unused; instead, stopping the service will just cause the -@code{waiting-for-termination?} slot be set to @code{#t}. - -@item -@vindex waiting-for-termination? (slot of ) -@code{waiting-for-termination?} cannot be initialized with a keyword -and should not be used by others, it is only used internally for -respawnable services when the @code{stop-delay?} slot contains a true -value. @code{waiting-for-termination?} contains @code{#t} if the -service is still running, but the user requested that it be stopped, -in which case if the service terminates the next time, the respawn -handler will not start it again. - -otherwise @code{#f}. - -@end itemize - -@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -@node Methods of services -@section Methods of services - -@deffn {method} start (obj ) -Start the service @var{obj}, including all the services it depends on. -It tries quite hard to do this: When a service that provides a -required symbol can not be started, it will look for another service -that also provides this symbol, until starting one such service -succeeds. There is some room for theoretical improvement here, of -course, but in pratice the current strategy already works very well. -This method returns the new value of the @code{running} slot -@ref{Slots of services}, which is @code{#f} if the service could not -be started. -@end deffn - -@deffn {method} stop (obj ) -This will stop the service @var{obj}, trying to stop services that -depend in it first, so they can be shutdown cleanly. If this will -fail, it will continue anyway. Stopping of services should usually -succeed, though. Otherwise, the behaviour is very similar to the -@code{start} method. The return value is also the new @code{running} -value, thus @code{#f} if the service was stopped. -@end deffn - -@deffn {method} action (obj ) the-action . args -Calls the action @var{the-action} (a symbol) of the service @var{obj}, -with the specified @var{args}, which have a meaning depending on the -particular action. -@end deffn - -@deffn {method} conflicts-with (obj ) -Returns a list of the canonical names of services that conflict with -the service @var{obj}. -@end deffn - -@deffn {method} canonical-name (obj ) -Returns the canonical name of @var{obj}, which is the first element of -the @code{provides} list. -@end deffn - -@deffn {method} provided-by (obj ) -Returns which symbols are provided by @var{obj}. -@end deffn - -@deffn {method} required-by (obj ) -Returns which symbols are required by @var{obj}. -@end deffn - -@deffn {method} running? (obj ) -Returns whether the service @var{obj} is running. -@end deffn - -@deffn {method} respawn? (obj ) -Returns whether the service @var{obj} should be respawned if it -terminates. -@end deffn - -@deffn {method} default-display-status (obj ) -Display status information about @var{obj}. This method is called -when the user performs the action @code{status} on @var{obj}, but -there is no specific implementation given for it. It is also called -when @code{detailed-status} is applied on the @code{root} service. -@end deffn - -@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -@node Service Convenience -@section Service Convenience - -In addition to the facilities listed below, there are also some -procedures that provide commonly needed constructors and destructors -for services @ref{Service De- and Constructors}. - -@deffn {procedure} register-services . services -Register all @var{services}, so that they can be taken into account -when trying to resolve dependencies. -@end deffn - -@deffn {procedure} lookup-services name -Return a list of all registered services which provide the symbol -@var{name}. -@end deffn - -@deffn {macro} make-actions (name proc) ... -This macro is used to create a value for the @code{actions} slot of a -service object @ref{Slots of services}. Each @var{name} is a symbol -and each @var{proc} the corresponding procedure that will be called to -perform the action. A @var{proc} has one argument, which will be the -current value of the @code{running} slot of the service. -@end deffn - -@deffn {method} start (obj ) -Start a registered service providing @var{obj}. -@end deffn - -@deffn {method} stop (obj ) -Stop a registered service providing @var{obj}. -@end deffn - -@deffn {method} action (obj ) the-action . args -The same as the @code{action} method of class @code{}, but -uses a service that provides @var{obj} and is running. -@end deffn - -@deffn {procedure} for-each-service proc -Call @var{proc}, a procedure taking one argument, once for each -registered service. -@end deffn - -@deffn {procedure} find-running services -Check if any of @var{services} is running. If this is the case, -return its canonical name. If not, return @code{#f}. Only the first -one will be returned; this is because this is mainly intended to be -applied on the return value of @code{lookup-services}. -@end deffn - -@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -@node Service De- and Constructors -@section Service De- and Constructors - -@cindex generating constructors -@cindex generating destructors -@cindex constructors, generation of -@cindex destructors, generation of -All of the procedures listed below return procedures generated from -the supplied arguments. These procedures take one argument in the -case of destructors and no arguments in the case of constructors. - -@deffn {procedure} make-system-constructor @var{command}@dots{} -The returned procedure will execute @var{command} in a shell and -return @code{#t} if execution was successful, otherwise @code{#f}. -For convenience, it takes multiple arguments which will be -concatenated first. -@end deffn - -@deffn {procedure} make-system-destructor @var{command}@dots{} -Similar to @code{make-system-constructor}, but returns @code{#f} if -execution of the @var{command} was successful, @code{#t} if not. -@end deffn - -@deffn {procedure} make-forkexec-constructor @var{command} @ - [#:user #f] @ - [#:group #f] @ - [#:pid-file #f] @ - [#:directory (default-service-directory)] @ - [#:environment-variables (default-environment-variables)] -Return a procedure that forks a child process, closes all file -descriptors except the standard output and standard error descriptors, s= ets -the current directory to @var{directory}, changes the environment to -@var{environment-variables} (using the @code{environ} procedure), sets t= he -current user to @var{user} and the current group to @var{group} unless t= hey -are @code{#f}, and executes @var{command} (a list of strings.) The resu= lt of -the procedure will be the PID of the child process. - -When @var{pid-file} is true, it must be the name of a PID file -associated with the process being launched; the return value is the PID -read from that file, once that file has been created. -@end deffn - -@deffn {procedure} make-kill-destructor [@var{signal}] -Returns a procedure that sends @var{signal} to the pid which it takes -as argument. This @emph{does} work together with respawning services, -because in that case the @code{stop} method of the @code{} -class sets the @code{running} slot to @code{#f} before actually -calling the destructor; if it would not do that, killing the process -in the destructor would immediately respawn the service. -@end deffn - -The @code{make-forkexec-constructor} procedure builds upon the following -procedures. - -@deffn {procedure} exec-command @var{command} @ - [#:user #f] @ - [#:group #f] @ - [#:directory (default-service-directory)] @ - [#:environment-variables (default-environment-variables)] -@deffnx {procedure} fork+exec-command @var{command} @ - [#:user #f] @ - [#:group #f] @ - [#:directory (default-service-directory)] @ - [#:environment-variables (default-environment-variables)] -Run @var{command} as the current process from @var{directory}, and with -@var{environment-variables} (a list of strings like @code{"PATH=3D/bin"}= .) -File descriptors 1 and 2 are kept as is, whereas file descriptor 0 -(standard input) points to @file{/dev/null}; all other file descriptors -are closed prior to yielding control to @var{command}. - -By default, @var{command} is run as the current user. If the -@var{user} keyword argument is present and not false, change to -@var{user} immediately before invoking @var{command}. @var{user} may -be a string, indicating a user name, or a number, indicating a user -ID. Likewise, @var{command} will be run under the current group, -unless the @var{group} keyword argument is present and not false. - -@code{fork+exec-command} does the same as @code{exec-command}, but in -a separate process whose PID it returns. -@end deffn - -@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -@node Service Examples -@section Service Examples - -FIXME: This needs a lot of work. - -You can create a service and then register it this way: - -@lisp -(define apache (make - #:provides '(apache) - #:start (...) - #:stop (...))) -(register-services apache) -@end lisp - -However, as you usually won't need a variable for the service, you can -pass it directly to @code{register-services}. Here is an example that -also specifies some more initial values for the slots: - -@lisp -(register-services - (make - #:provides '(apache-2.0 apache httpd) - #:requires '() - #:start (...) - #:stop (...) - #:actions (make-actions - (reload-modules (...)) - (restart (...))))) -@end lisp - -@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -@node The root and unknown services -@section The @code{root} and @code{unknown} services - -@cindex root service -@cindex special services -The service @code{root} is special, because it is used to control the -Shepherd itself. It has an alias @code{shepherd}. It provides the -following actions (in addition to @code{enable}, @code{disable} and -@code{restart} which do not make sense here). - -@table @code -@item status -Displays which services are started and which ones are not. - -@item detailed-status -Displays detailed information about every registered service. - -@item load @var{file} -Evaluate the Scheme code in @var{file} in a fresh module that uses the -@code{(oop goops)} and @code{(shepherd services)} modules---as with the -@code{--config} option of @command{shepherd} (@pxref{Invoking shepherd})= . - -@item unload @var{service-name} -Attempt to remove the service identified by @var{service-name}. -@command{shepherd} will first stop the service, if necessary, and then -remove it from the list of registered services. Any services -depending upon @var{service-name} will be stopped as part of this -process. - -If @var{service-name} simply does not exist, output a warning and do -nothing. If it exists, but is provided by several services, output a -warning and do nothing. This latter case might occur for instance with -the fictional service @code{web-server}, which might be provided by both -@code{apache} and @code{nginx}. If @var{service-name} is the special -string and @code{all}, attempt to remove all services except for the She= pherd -itself. - -@item reload @var{file-name} -Unload all known optional services using unload's @code{all} option, -then load @var{file-name} using @code{load} functionality. If -file-name does not exist or @code{load} encounters an error, you may -end up with no defined services. As these can be reloaded at a later -stage this is not considered a problem. If the @code{unload} stage -fails, @code{reload} will not attempt to load @var{file-name}. - -@item daemonize -Fork and go into the background. This should be called before -respawnable services are started, as otherwise we would not get the -@code{SIGCHLD} signals when they terminate. - -@item enable-persistency -When terminating, safe the list of running services in a file. -@c FIXME-CRITICAL: How can we specify which one? - -@item disable-persistency -Don't safe the list of running services when terminating. - -@end table - -@cindex unknown service -@cindex fallback service -The @code{unknown} service must be defined by the user and if it -exists, is used as a fallback whenever we try to invoke an unknown -action of an existing service or use a service that does not exist. -This is useful only in few cases, but enables you to do various sorts -of unusual things. - -@c FIXME-CRITICAL: finish - -@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -@node Runlevels -@chapter Runlevels - -RUNLEVELS DO NOT WORK YET! Do not use them! Ignore this section! - -@cindex runlevel -@tindex -A @dfn{runlevel} makes it easier to start and stop groups of services, -to bring the system into a certain state. An object of class -@code{} is an abstract runlevel, and has the following -methods: - -@deffn {method} enter (rl ) services -This will be called when the runlevel should be entered. -@var{services} is the list of the currently running services. -@end deffn - -@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -@node Misc Facilities -@chapter Misc Facilities - -This is a list of facilities which are available to code running -inside of the Shepherd and is considered generally useful, but is not di= rectly -related to one of the other topic covered in this manual. - -@menu -* Errors:: Signalling, handling and ignoring errors. -* Communication:: Input/Output in various ways. -* Others:: Stuff that is useful, but is homeless. -@end menu - -@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -@node Errors -@section Errors - -@cindex assertions -@deffn {macro} assert expr -If @var{expr} yields @code{#f}, display an appropriate error -message and throw an @code{assertion-failed} exception. -@end deffn - -@deffn {procedure} caught-error key args -Tell the Shepherd that a @var{key} error with @var{args} has occured. T= his is -the simplest way to cause caught error result in uniformly formated -warning messages. The current implementation is not very good, -though. -@end deffn - -@deffn {procedure} call/cc proc -An alias for @code{call-with-current-continuation}. -@end deffn - -@deffn {procedure} call/ec proc -A simplistic implementation of the nonstandard, but popular procedure -@code{call-with-escape-continuation}, i.e. a @code{call/cc} for -outgoing continuations only. Note that the variant included in the Shep= herd is -not aware of @code{dynamic-wind} at all and does not yet support -returning multiple values. -@end deffn - -@cindex system errors -@deffn {macro} without-system-error expr@dots{} -Evaluates the @var{expr}s, not going further if a system error occurs, -but also doing nothing about it. -@end deffn - -@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -@node Communication -@section Communication - -The @code{(shepherd comm)} module provides primitives that allow clients= such -as @command{herd} to connect to @command{shepherd} and send it commands = to -control or change its behavior (@pxref{Slots of services, actions of -services}). - -@tindex -Currently, clients may only send @dfn{commands}, represented by the -@code{} type. Each command specifies a service it -applies to, an action name, a list of strings to be used as arguments, -and a working directory. Commands are instantiated with -@code{shepherd-command}: - -@deffn {procedure} shepherd-command @var{action} @var{service} @ - [#:@var{arguments} '()] [#:@var{directory} (getcwd)] -Return a new command (a @code{}) object for -@var{action} on @var{service}. -@end deffn - -@noindent -Commands may then be written to or read from a communication channel -with the following procedures: - -@deffn {procedure} write-command @var{command} @var{port} -Write @var{command} to @var{port}. -@end deffn - -@deffn {procedure} read-command @var{port} -Receive a command from @var{port} and return it. -@end deffn - -In practice, communication with @command{shepherd} takes place over a -Unix-domain socket, as discussed earlier (@pxref{Invoking shepherd}). -Clients may open a connection with the procedure below. - -@deffn {procedure} open-connection [@var{file}] -Open a connection to the daemon, using the Unix-domain socket at -@var{file}, and return the socket. - -When @var{file} is omitted, the default socket is used. -@end deffn - -@cindex output -The daemon writes output to be logged or passed to the -currently-connected client using @code{local-output}: - -@deffn {procedure} local-output format-string . args -This procedure should be used for all output operations in the Shepherd.= It -outputs the @var{args} according to the @var{format-string}, then -inserts a newline. It writes to whatever is the main output target of -the Shepherd, which might be multiple at the same time in future version= s. -@end deffn - -@cindex protocol, between @command{shepherd} and its clients -Under the hood, @code{write-command} and @code{read-command} write/read -commands as s-expressions (sexps). Each sexp is intelligible and -specifies a protocol version. The idea is that users can write their -own clients rather than having to invoke @command{herd}. For instance, -when you type @command{herd status}, what is sent over the wire is the -following sexp: - -@lisp -(shepherd-command - (version 0) - (action status) (service root) - (arguments ()) (directory "/data/src/dmd")) -@end lisp - -The reply is also an sexp, along these lines: - -@lisp -(reply (version 0) - (result (((service @dots{}) @dots{}))) - (error #f) (messages ())) -@end lisp - -This reply indicates that the @code{status} action was successful, -because @code{error} is @code{#f}, and gives a list of sexps denoting -the status of services as its @code{result}. The @code{messages} field -is a possibly-empty list of strings meant to be displayed as is to the -user. - - -@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -@node Others -@section Others - -@cindex hashes -@deffn {procedure} copy-hashq-table table new-size -Create a hash-table with size @var{new-size}, and insert all values -from @var{table} into it, using @code{eq?} when inserting. This -procedure is mainly used internally, but is a generally useful -utillity, so it can by used by everyone. -@end deffn - -@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -@node Internals -@chapter Internals - -This chapter contains information about the design and the -implementation details of the Shepherd for people who want to hack it. - -The GNU@tie{}Shepherd is developed by a group of people in connection -with @uref{https://www.gnu.org/software/guix/, GuixSD}, GNU's advanced -distribution, but it can be used on other distros as well. You're very -much welcome to join us! You can report bugs to -@email{bug-guix@@gnu.org} and send patches or suggestions to -@email{guix-devel@@gnu.org}. - -@menu -* Coding standards:: How to properly hack the Shepherd. -* Design decisions:: Why the Shepherd is what it is. -* Service Internals:: How services actually work. -* Runlevel evolution:: Learning from past mistakes. -@end menu - -@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -@node Coding standards -@section Coding standards - -About formatting: Use common sense and GNU Emacs (which actually is -the same, of course), and you almost can't get the formatting wrong. -Formatting should be as in Guile and Guix, basically. @xref{Coding -Style,,, guix, GNU Guix Reference Manual}, for more info. - -@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -@node Design decisions -@section Design decisions - -@quotation Note -This section was written by Wolfgang J=C3=A4hrling back in 2003 and docu= ments -the original design of what was then known as GNU@tie{}dmd. The main -ideas remain valid but some implementation details and goals have -changed. -@end quotation - -The general idea of a service manager that uses dependencies, similar -to those of a Makefile, came from the developers of the GNU Hurd, but -as few people are satisfied with System V Init, many other people had -the same idea independently. Nevertheless, the Shepherd was written wit= h the -goal of becoming a replacement for System V Init on GNU/Hurd, which -was one of the reasons for choosing the extension language of the GNU -project, Guile, for implementation (another reason being that it makes -it just so much easier). - -The runlevel concept (i.e. thinking in @emph{groups} of services) is -sometimes useful, but often one also wants to operate on single -services. System V Init makes this hard: While you can start and stop -a service, @code{init} will not know about it, and use the runlevel -configuration as its source of information, opening the door for -inconsistencies (which fortunatly are not a practical problem -usually). In the Shepherd, this was avoided by having a central entity = that is -responsible for starting and stopping the services, which therefore -knows which services are actually started (if not completely -inproperly used, but that is a requirement which is impossible to -avoid anyway). While runlevels are not implemented yet, it is clear -that they will sit on top of the service concept, i.e. runlevels will -merely be an optional extension that the service concept does not rely -on. This also makes changes in the runlevel design easier when it may -become necessary. - -The consequence of having a daemon running that controls the services -is that we need another program as user interface which communicates -with the daemon. Fortunatly, this makes the commands necessary for -controlling services pretty short and intuitive, and gives the -additional bonus of adding some more flexibility. For example, it is -easiely possible to grant password-protected control over certain -services to unprivileged users, if desired. - -An essential aspect of the design of the Shepherd (which was already men= tioned -above) is that it should always know exactly what is happening, -i.e. which services are started and stopped. The alternative would -have been to not use a daemon, but to save the state on the file -system, again opening the door for inconsistencies of all sorts. -Also, we would have to use a seperate program for respawning a service -(which just starts the services, waits until it terminates and then -starts it again). Killing the program that does the respawning (but -not the service that is supposed to be respawned) would cause horrible -confusion. My understanding of ``The Right Thing'' is that this -conceptionally limited strategy is exactly what we do not want. - -The way dependencies work in the Shepherd took a while to mature, as it = was not -easy to figure out what is appropriate. I decided to not make it too -sophisticated by trying to guess what the user might want just to -theoretically fulfill the request we are processing. If something -goes wrong, it is usually better to tell the user about the problem -and let her fix it, taking care to make finding solutions or -workarounds for problems (like a misconfigured service) easy. This -way, the user is in control of what happens and we can keep the -implementation simple. To make a long story short, @emph{we don't try -to be too clever}, which is usually a good idea in developing -software. - -If you wonder why I was giving a ``misconfigured service'' as an -example above, consider the following situation, which actually is a -wonderful example for what was said in the previous paragraph: Service -X depends on symbol S, which is provided by both A and B. A depends -on AA, B depends on BB. AA and BB conflict with each other. The -configuration of A contains an error, which will prevent it from -starting; no service is running, but we want to start X now. In -resolving its dependencies, we first try to start A, which will cause -AA to be started. After this is done, the attempt of starting A -fails, so we go on to B, but its dependency BB will fail to start -because it conflicts with the running service AA. So we fail to -provide S, thus X cannot be started. There are several possibilities -to deal with this: - -@itemize @bullet -@item -When starting A fails, terminate those services which have been -started in order to fulfill its dependencies (directly and -indirectly). In case AA was running already, we would not want to -terminate it. Well, maybe we would, to avoid the conflict with BB. -But even if we would find out somehow that we need to terminate AA to -eventually start X, is the user aware of this and wants this to happen -(assuming AA was running already)? Probably not, she very likely has -assumed that starting A succeeds and thus terminating AA is not -necessary. Remember, unrelated (running) services might depend in AA. -Even if we ignore this issue, this strategy is not only complicated, -but also far from being perfect: Let's assume starting A succeeds, but -X also depends on a service Z, which requires BB. In that case, we -would need to detect in the first place that we should not even try to -start A, but directly satisfy X's dependency on S with B. - -@item -We could do it like stated above, but stop AA only if we know we won't -need it anymore (for resolving further dependencies), and start it -only when it does not conflict with anything that needs to get -started. But should we stop it if it conflicts with something that -@emph{might} get started? (We do not always know for sure what we -will start, as starting a service might fail and we want to fall back -to a service that also provides the particular required symbol in that -case.) I think that either decision will be bad in one case or -another, even if this solution is already horribly complicated. - -@item -When we are at it, we could just calculate a desired end-position, and -try to get there by starting (and stopping!) services, recalculating -what needs to be done whenever starting a service fails, also marking -that particular service as unstartable, except if it fails to start -because a dependency could not be resolved (or maybe even then?). -This is even more complicated. Instead of implementing this and -thereby producing code that (a) nobody understands, (b) certainly has -a lot of bugs, (c) will be unmaintainable and (d) causes users to -panic because they won't understand what will happen, I decided to do -the following instead: - -@item -Just report the error, and let the user fix it (in this case, fix the -configuration of A) or work around it (in this case, disable A so that -we won't start AA but directly go on to starting B). -@end itemize - -I hope you can agree that the latter solution after all is the best -one, because we can be sure to not do something that the user does not -want us to do. Software should not run amok. This explanation was -very long, but I think it was necessary to justify why the Shepherd uses= a very -primitive algorithm to resolve dependencies, despite the fact that it -could theoretically be a bit more clever in certain situations. - -One might argue that it is possible to ask the user if the planned -actions are ok with her, and if the plan changes ask again, but -especially given that services are supposed to usually work, I see few -reasons to make the source code of the Shepherd more complicated than -necessary. If you volunteer to write @emph{and} maintain a more -clever strategy (and volunteer to explain it to everyone who wants to -understand it), you are welcome to do so, of course@dots{} - -@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -@node Service Internals -@section Service Internals - -@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -@node Runlevel evolution -@section Runlevel evolution - -@quotation Note -This section was written by Wolfgang J=C3=A4hrling back in 2003 and is k= ept -mostly for historians to read. -@end quotation - -This section describes how the runlevel concept evolved over time. -This is basically a collection of mistakes, but is provided here for -your information, and possibly for your amusement, but I'm not sure if -all this weird dependency stuff is really that funny. - -@menu -* Runlevel assumptions:: What runlevels should be like -* Runlevels - part one:: The first attempts of making it work -* Runlevels - part two:: It should work... somehow... -@end menu - -@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -@node Runlevel assumptions -@subsection Runlevel assumptions - -A runlevel is a system state, i.e. it consists of the information -about which services are supposed to be available and which not. This -vague definition implies that several different runlevel styles can be -implemented in a service manager. - -For example, you can do it like System V Init, specifying which -services should be started when we enter a runlevel and which ones -should be stopped when leaving it. But one could also specify for -every service in which runlevels it should be running. - -In the Shepherd, we do not want to limit ourselfes to a single runlevel = style. -We allow for all possible strategies to be implemented, providing the -most useful ones as defaults. We also want to make it possible to -combine the different styles arbitrariely. - -Therefore, when entering a runlevel, we call a user-defined piece of -code, passing it the list of currently active services and expecting -as the result a list of service symbols which tell us which services -we want to have running. This interface makes it very easy to -implement runlevel styles, but makes it not-so-easy for the runlevel -implementation itself, because we have to get from the current state -into a desired state, which might be more or less vague (since it is -not required to be a list of canonical names). Obviously service -conflicts and already running services need to be taken into account -when deciding which services should be used to provide the various -symbols. - -Also, the runlevel implementation should be implemented completely on -top of the service concept, i.e. the service part should not depend on -the idea of runlevels or care about them at all. Otherwise -understanding the service part (which is the most essential aspect of -the Shepherd) would become harder than necessary. - -@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -@node Runlevels - part one -@subsection Runlevels, part one - -I came up with the following method (here in Pseudo-Scheme), which is -possibly slightly buggy, but should give you the idea: - -@lisp -;; Beginning with the canonical names in CURRENT-SERVICES, start and -;; stop services until getting into a state where everything requested -;; in TARGET-SERVICES (which does not only consist of canonical names) -;; is provided, and the things they depends on, but no more. -(define (switch-runlevel current-services target-services) - (let ((target-services-backup target-services) - (unstartable '())) - (let retry () - (repeat-until-none-of-these-changes-annythig - ;; Replace all of them with canonical names which provide them. - (canonicalize-names! target-services unstartable current-services= ) - ;; Add what we need additionally. - (add-dependencies! target-services unstartable current-services)) - (remove-redundancy! target-services) - (stop-all-unneeded target-services) - (catch 'service-could-not-be-started - (lambda () - ;; Iterate over the list, starting only those which - ;; have all dependencies already resolved, so nothing - ;; we don't want will be started. Repeat until done. - (carefully-start target-services)) - (lambda (key service) - (set! unstartable (cons service unstartable)) - (set! target-services backup-target-services) - (set! current-services (compute-current-services)) - (retry)))))) -@end lisp - -This indeed looks like a nice way to get what we want. However, the -details of this are not as easy as it looks like. When replacing -virtual services with canonical names, we have to be very careful. -Consider the following situation: - -The virtual service X is provided by both A and B, while Y is provided -only by B. We want to start C (which depends on X) and D (which -depends on Y). Obviously we should use B to fulfill the dependency -of C and D on X and Y, respectively. But when we see that we need -something that provides X, we are likely to do the wrong thing: Select -A. Thus, we need to clean this up later. I wanted to do this as -follows: - -While substituting virtual services with canonical names, we also safe -which one we selected to fulfill what, like this: - -@lisp -((A . (X)) - (B . (Y))) -@end lisp - -Later we look for conflicts, and as A and B conflict, we look which -one can be removed (things they provide but are not required by anyone -should be ignored, thus we need to create a list like the above). In -this case, we can replace A with B as B also provides X (but A does -not provide Y, thus the reverse is impossible). If both could be -used, we probably should decide which one to use by looking at further -conflicts, which gets pretty hairy. But, in this case, we are lucky -and end up with this: - -@lisp -((B . (X Y))) -@end lisp - -This way of finding out which service we should use in case of -conflicts sounds pretty sane, but if you think it will work well, you -have been fooled, because actually it breaks horribly in the following -situation: - -@multitable @columnfractions .10 .30 -@item Service @tab Provides -@item A @tab @code{W X Y -} -@item B @tab @code{W X - Z} -@item C @tab @code{- X Y Z} -@item D @tab @code{W - - -} -@end multitable - -If we need all of W, X, Y and Z, then obviously we need to take C and -D. But if we have a list like this, we cannot fix it: - -@lisp -((A . (W X Y)) - (B . (Z))) -@end lisp - -Thus, we cannot do it this way. - -@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -@node Runlevels - part two -@subsection Runlevels, part two - -Let's look again at the table at the end of part two: - -@multitable @columnfractions .10 .30 -@item Service @tab Provides -@item A @tab @code{W X Y -} -@item B @tab @code{W X - Z} -@item C @tab @code{- X Y Z} -@item D @tab @code{W - - -} -@end multitable - -If from this table it is so obvious for us what we should do, then it -should also be possible to calculate it for a computer, given such a -table as input. Ok, we have to take into account conflicts that are -not visible in this table, but the general idea is usable. But how do -we find which combination works? I found only one way yet: Kind of a -brute force attack: Try combinations until we find one that works. - -This alone would be too slow. With 20 services we would have 2^20 -possible combinations, that is a bit more than a million. Fortunatly, -we can optimize this. First I thought we could remove all services -from the list that do not provide any symbol we need, but that is -obviously a stupid idea, as we might need them for dependencies, in -which case we need to take into account their conflicts. But the -following method would work: - -Very often a symbol that is required will be a canonical name already, -i.e. be provided only by a single service. Using our example above, -let's suppose we also need the symbol V, which is provided only by D. -The first step we do is to look which (required) symbols are provided -only by a single service, as we will need this service for sure. In -this case, we would need D. But by using it, we would also get the -other symbols it provides, W in this case. This means that we don't -need to bother looking at other services that provide W, as we cannot -use them because they conflict with a service that we definitely need. -In this case, we can remove A and B from the list this way. Note that -we can remove them entirely, as all their conflicts become irrelevant -to us now. In this simple case we would not even have to do much -else, C is the only remaining service. - -After this first step, there remain the symbols that are provided by -two or more services. In every combination we try, exactly one of -them must be used (and somehow we should take into account which -services are running already). This also reduces the amount of -possible combinations a lot. So what remains after that are the -services we might need for fulfilling dependencies. For them, we -could try all combinations (2^n), making sure that we always try -subsets before any of their supersets to avoid starting unneeded -services. We should take into account which services are already -running as well. - -The remaining question is, what to do if starting a service fails. A -simple solution would be to recursively remove all services that -depend on it directly or indirectly. That might cause undesired -side-effects, if a service was running but it had to be stopped -because one of the services that provides something it depends on gets -exchanged for another service that provides the same symbol, but fails -to start. The fact that we would have to stop the (first) service is -a problem on its own, though. - - -@c ********************************************************************* -@node GNU Free Documentation License -@appendix GNU Free Documentation License - -@include fdl-1.3.texi - -@c @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -@node Concept Index -@unnumbered Concept Index - -@printindex cp - -@node Procedure and Macro Index -@unnumbered Procedure and Macro Index - -@printindex fn - -@node Variable Index -@unnumbered Variable Index - -@printindex vr - -@node Type Index -@unnumbered Type Index - -@printindex tp - -@bye --------------2.7.0.rc3--