diff options
Diffstat (limited to 'en_US.ISO8859-1/books')
23 files changed, 6832 insertions, 69 deletions
diff --git a/en_US.ISO8859-1/books/arch-handbook/Makefile b/en_US.ISO8859-1/books/arch-handbook/Makefile index 9ad49d0e62..5f933755f9 100644 --- a/en_US.ISO8859-1/books/arch-handbook/Makefile +++ b/en_US.ISO8859-1/books/arch-handbook/Makefile @@ -10,8 +10,6 @@ DOC?= book FORMATS?= html-split -HAS_INDEX= true - INSTALL_COMPRESSED?= gz INSTALL_ONLY_COMPRESSED?= diff --git a/en_US.ISO8859-1/books/arch-handbook/chapters.ent b/en_US.ISO8859-1/books/arch-handbook/chapters.ent index 7fdd3df4ad..5182a6f8fb 100644 --- a/en_US.ISO8859-1/books/arch-handbook/chapters.ent +++ b/en_US.ISO8859-1/books/arch-handbook/chapters.ent @@ -10,8 +10,6 @@ $FreeBSD$ --> -<!ENTITY % chap.index "IGNORE"> - <!-- Part one - Kernel --> <!ENTITY chap.boot SYSTEM "boot/chapter.xml"> <!ENTITY chap.kobj SYSTEM "kobj/chapter.xml"> @@ -33,7 +31,4 @@ <!ENTITY chap.pccard SYSTEM "pccard/chapter.xml"> <!-- Part three - Appendices --> -<![%chap.index;[ - <!ENTITY chap.index SYSTEM "index.xml"> -]]> -<!ENTITY chap.index ""> +<!ENTITY chap.index "<index xmlns='http://docbook.org/ns/docbook'/>"> diff --git a/en_US.ISO8859-1/books/arch-handbook/mac.ent b/en_US.ISO8859-1/books/arch-handbook/mac.ent index e05ac48e87..76a5938a76 100644 --- a/en_US.ISO8859-1/books/arch-handbook/mac.ent +++ b/en_US.ISO8859-1/books/arch-handbook/mac.ent @@ -3,11 +3,11 @@ <!ENTITY mac.mpo "mpo"> <!ENTITY mac.thead ' - <colspec colname="first" colwidth="0"/> - <colspec colwidth="0"/> - <colspec colname="last" colwidth="0"/> + <colspec xmlns="http://docbook.org/ns/docbook" colname="first" colwidth="0"/> + <colspec xmlns="http://docbook.org/ns/docbook" colwidth="0"/> + <colspec xmlns="http://docbook.org/ns/docbook" colname="last" colwidth="0"/> - <thead> + <thead xmlns="http://docbook.org/ns/docbook"> <row> <entry>Parameter</entry> <entry>Description</entry> @@ -17,14 +17,14 @@ '> <!ENTITY mac.externalize.paramdefs ' - <paramdef>struct label *<parameter>label</parameter></paramdef> - <paramdef>char *<parameter>element_name</parameter></paramdef> - <paramdef>struct sbuf *<parameter>sb</parameter></paramdef> - <paramdef>int <parameter>*claimed</parameter></paramdef> + <paramdef xmlns="http://docbook.org/ns/docbook">struct label *<parameter>label</parameter></paramdef> + <paramdef xmlns="http://docbook.org/ns/docbook">char *<parameter>element_name</parameter></paramdef> + <paramdef xmlns="http://docbook.org/ns/docbook">struct sbuf *<parameter>sb</parameter></paramdef> + <paramdef xmlns="http://docbook.org/ns/docbook">int <parameter>*claimed</parameter></paramdef> '> <!ENTITY mac.externalize.tbody ' - <tbody> + <tbody xmlns="http://docbook.org/ns/docbook"> <row> <entry><parameter>label</parameter></entry> <entry>Label to be externalized</entry> @@ -49,11 +49,11 @@ </tbody> '> -<!ENTITY mac.externalize.para " - <para>Produce an externalized label based on the label structure passed. +<!ENTITY mac.externalize.para ' + <para xmlns="http://docbook.org/ns/docbook">Produce an externalized label based on the label structure passed. An externalized label consists of a text representation of the label contents that can be used with userland applications and read by the - user. Currently, all policies' <function>externalize</function> entry + user. Currently, all policies' <function>externalize</function> entry points will be called, so the implementation should check the contents of <parameter>element_name</parameter> before attempting to fill in <parameter>sb</parameter>. If @@ -62,17 +62,17 @@ if an error occurs while externalizing the label data. Once the policy fills in <parameter>element_data</parameter>, <varname>*claimed</varname> should be incremented.</para> -"> +'> <!ENTITY mac.internalize.paramdefs ' - <paramdef>struct label *<parameter>label</parameter></paramdef> - <paramdef>char *<parameter>element_name</parameter></paramdef> - <paramdef>char *<parameter>element_data</parameter></paramdef> - <paramdef>int *<parameter>claimed</parameter></paramdef> + <paramdef xmlns="http://docbook.org/ns/docbook">struct label *<parameter>label</parameter></paramdef> + <paramdef xmlns="http://docbook.org/ns/docbook">char *<parameter>element_name</parameter></paramdef> + <paramdef xmlns="http://docbook.org/ns/docbook">char *<parameter>element_data</parameter></paramdef> + <paramdef xmlns="http://docbook.org/ns/docbook">int *<parameter>claimed</parameter></paramdef> '> <!ENTITY mac.internalize.tbody ' - <tbody> + <tbody xmlns="http://docbook.org/ns/docbook"> <row> <entry><parameter>label</parameter></entry> <entry>Label to be filled in</entry> @@ -96,9 +96,9 @@ </tbody> '> -<!ENTITY mac.internalize.para " - <para>Produce an internal label structure based on externalized label data - in text format. Currently, all policies' <function>internalize</function> +<!ENTITY mac.internalize.para ' + <para xmlns="http://docbook.org/ns/docbook">Produce an internal label structure based on externalized label data + in text format. Currently, all policies' <function>internalize</function> entry points are called when internalization is requested, so the implementation should compare the contents of <parameter>element_name</parameter> to its own name in order to be sure @@ -108,4 +108,4 @@ <parameter>element_name</parameter> does not match its own name, or when data can successfully be internalized, in which case <varname>*claimed</varname> should be incremented.</para> -"> +'> diff --git a/en_US.ISO8859-1/books/bibliography/book.xml b/en_US.ISO8859-1/books/bibliography/book.xml index 778160a2be..c9b97ef1bf 100644 --- a/en_US.ISO8859-1/books/bibliography/book.xml +++ b/en_US.ISO8859-1/books/bibliography/book.xml @@ -1,20 +1,17 @@ <?xml version="1.0" encoding="iso-8859-1"?> -<!DOCTYPE book PUBLIC "-//FreeBSD//DTD DocBook XML V4.5-Based Extension//EN" - "../../../share/xml/freebsd45.dtd" [ +<!DOCTYPE book PUBLIC "-//FreeBSD//DTD DocBook XML V5.0-Based Extension//EN" "../../../share/xml/freebsd50.dtd" [ <!ENTITY bibliography SYSTEM "../../../share/xml/bibliography.xml"> ]> - <!-- The FreeBSD Documentation Project $FreeBSD$ --> - -<book lang='en'> - <bookinfo> +<book xmlns="http://docbook.org/ns/docbook" xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0" xml:lang="en"> + <info> <title>FreeBSD Bibliography</title> - <corpauthor>The FreeBSD Documentation Project</corpauthor> + <author><orgname>The FreeBSD Documentation Project</orgname></author> <pubdate>February 1999</pubdate> @@ -24,7 +21,7 @@ </copyright> <releaseinfo>$FreeBSD$</releaseinfo> - </bookinfo> + </info> &bibliography; </book> diff --git a/en_US.ISO8859-1/books/developers-handbook/Makefile b/en_US.ISO8859-1/books/developers-handbook/Makefile index 2d673e307e..8c5bb2209c 100644 --- a/en_US.ISO8859-1/books/developers-handbook/Makefile +++ b/en_US.ISO8859-1/books/developers-handbook/Makefile @@ -10,8 +10,6 @@ DOC?= book FORMATS?= html-split -HAS_INDEX= true - INSTALL_COMPRESSED?= gz INSTALL_ONLY_COMPRESSED?= diff --git a/en_US.ISO8859-1/books/developers-handbook/chapters.ent b/en_US.ISO8859-1/books/developers-handbook/chapters.ent index 555d115d40..795553bda9 100644 --- a/en_US.ISO8859-1/books/developers-handbook/chapters.ent +++ b/en_US.ISO8859-1/books/developers-handbook/chapters.ent @@ -10,8 +10,6 @@ $FreeBSD$ --> -<!ENTITY % chap.index "IGNORE"> - <!-- Part one --> <!ENTITY chap.introduction SYSTEM "introduction/chapter.xml"> <!ENTITY chap.tools SYSTEM "tools/chapter.xml"> @@ -32,7 +30,4 @@ <!ENTITY chap.x86 SYSTEM "x86/chapter.xml"> <!-- Part six - Appendices --> -<![%chap.index;[ - <!ENTITY chap.index SYSTEM "index.xml"> -]]> -<!ENTITY chap.index ""> +<!ENTITY chap.index "<index xmlns='http://docbook.org/ns/docbook'/>"> diff --git a/en_US.ISO8859-1/books/faq/book.xml b/en_US.ISO8859-1/books/faq/book.xml index 30a1e5be59..886c6b2f43 100644 --- a/en_US.ISO8859-1/books/faq/book.xml +++ b/en_US.ISO8859-1/books/faq/book.xml @@ -3,18 +3,18 @@ "../../../share/xml/freebsd45.dtd" [ <!ENTITY bibliography SYSTEM "../../../share/xml/bibliography.xml"> <!ENTITY rel.numbranch "3"> <!-- number of branches that follow in this list --> -<!ENTITY rel.head "<emphasis>10-CURRENT</emphasis>"> -<!ENTITY rel.head.relx "10.<replaceable>X</replaceable>"> -<!ENTITY rel.head.releng "<symbol>head/</symbol>"> +<!ENTITY rel.head "<emphasis xmlns='http://docbook.org/ns/docbook'>10-CURRENT</emphasis>"> +<!ENTITY rel.head.relx "10.<replaceable xmlns='http://docbook.org/ns/docbook'>X</replaceable>"> +<!ENTITY rel.head.releng "<symbol xmlns='http://docbook.org/ns/docbook'>head/</symbol>"> <!ENTITY rel.head.packages "packages-10-current"> -<!ENTITY rel.relx "9.<replaceable>X</replaceable>"> -<!ENTITY rel.stable "<emphasis>9-STABLE</emphasis>"> -<!ENTITY rel.releng "<symbol>stable/9/</symbol>"> +<!ENTITY rel.relx "9.<replaceable xmlns='http://docbook.org/ns/docbook'>X</replaceable>"> +<!ENTITY rel.stable "<emphasis xmlns='http://docbook.org/ns/docbook'>9-STABLE</emphasis>"> +<!ENTITY rel.releng "<symbol xmlns='http://docbook.org/ns/docbook'>stable/9/</symbol>"> <!ENTITY rel.relengdate "September 2011"> <!ENTITY rel.packages "packages-9-stable"> -<!ENTITY rel2.relx "8.<replaceable>X</replaceable>"> -<!ENTITY rel2.stable "<emphasis>8-STABLE</emphasis>"> -<!ENTITY rel2.releng "<symbol>stable/8/</symbol>"> +<!ENTITY rel2.relx "8.<replaceable xmlns='http://docbook.org/ns/docbook'>X</replaceable>"> +<!ENTITY rel2.stable "<emphasis xmlns='http://docbook.org/ns/docbook'>8-STABLE</emphasis>"> +<!ENTITY rel2.releng "<symbol xmlns='http://docbook.org/ns/docbook'>stable/8/</symbol>"> <!ENTITY rel2.relengdate "August 2009"> <!ENTITY rel2.packages "packages-8-stable"> ]> diff --git a/en_US.ISO8859-1/books/fdp-primer/book.xml b/en_US.ISO8859-1/books/fdp-primer/book.xml index c1e16f1040..7daf24e427 100644 --- a/en_US.ISO8859-1/books/fdp-primer/book.xml +++ b/en_US.ISO8859-1/books/fdp-primer/book.xml @@ -265,7 +265,5 @@ The time is 09:18</screen></entry> &app.examples; -<!-- - &index; ---> + <index/> </book> diff --git a/en_US.ISO8859-1/books/fdp-primer/psgml-mode/chapter.xml b/en_US.ISO8859-1/books/fdp-primer/psgml-mode/chapter.xml new file mode 100644 index 0000000000..6e8dd4ef35 --- /dev/null +++ b/en_US.ISO8859-1/books/fdp-primer/psgml-mode/chapter.xml @@ -0,0 +1,172 @@ +<?xml version="1.0" encoding="iso-8859-1"?> +<!-- Copyright (c) 1998, 1999 Nik Clayton, All rights reserved. + + Redistribution and use in source (SGML DocBook) and 'compiled' forms + (SGML HTML, PDF, PostScript, RTF and so forth) with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code (SGML DocBook) must retain the above + copyright notice, this list of conditions and the following + disclaimer as the first lines of this file unmodified. + + 2. Redistributions in compiled form (transformed to other DTDs, + converted to PDF, PostScript, RTF and other formats) must reproduce + the above copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS DOCUMENTATION IS PROVIDED BY NIK CLAYTON "AS IS" AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL NIK CLAYTON BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS DOCUMENTATION, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + $FreeBSD$ +--> + +<chapter id="psgml-mode"> + <title>Using <literal>sgml-mode</literal> with + <application>Emacs</application></title> + + <para>Recent versions of <application>Emacs</application> or + <application>XEmacs</application> (available from the Ports + Collection) contain a very useful package called PSGML (can be + installed from <filename role="package">editors/psgml</filename>). + Automatically invoked when a file with the + <filename>.xml</filename> extension is loaded, or by typing + <command>M-x sgml-mode</command>, it is a major mode for dealing + with SGML files, elements and attributes.</para> + + <para>An understanding of some of the commands provided by this mode + can make working with SGML documents such as the Handbook much + easier.</para> + + <variablelist> + <varlistentry> + <term><command>C-c C-e</command></term> + + <listitem> + <para>Runs <function>sgml-insert-element</function>. You will + be prompted for the name of the element to insert at the + current point. You can use the <keycap>Tab</keycap> key to + complete the element. Elements that are not valid at the + current point will be disallowed.</para> + + <para>The start and end tags for the element will be inserted. + If the element contains other, mandatory, elements then + these will be inserted as well.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><command>C-c =</command></term> + + <listitem> + <para>Runs <function>sgml-change-element-name</function>. + Place the point within an element and run this command. You + will be prompted for the name of the element to change to. + Both the start and end tags of the current element will be + changed to the new element.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><command>C-c C-r</command></term> + + <listitem> + <para>Runs <function>sgml-tag-region</function>. Select some + text (move to start of text, <command>C-space</command>, + move to end of text, <command>C-space</command>) and then + run this command. You will be prompted for the element to + use. This element will then be inserted immediately before + and after your marked region.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><command>C-c -</command></term> + + <listitem> + <para>Runs <function>sgml-untag-element</function>. Place the + point within the start or end tag of an element you want to + remove, and run this command. The element's start and end + tags will be removed.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><command>C-c C-q</command></term> + + <listitem> + <para>Runs <function>sgml-fill-element</function>. Will + recursively fill (i.e., reformat) content from the current + element in. The filling <emphasis>will</emphasis> affect + content in which whitespace is significant, such as within + <sgmltag>programlisting</sgmltag> elements, so run this + command with care.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><command>C-c C-a</command></term> + + <listitem> + <para>Runs <function>sgml-edit-attributes</function>. Opens a + second buffer containing a list of all the attributes for + the closest enclosing element, and their current values. + Use <keycap>Tab</keycap> to navigate between attributes, + <command>C-k</command> to remove an existing value and + replace it with a new one, <command>C-c C-c</command> to + close this buffer and return to the main document.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><command>C-c C-v</command></term> + + <listitem> + <para>Runs <function>sgml-validate</function>. Prompts you to + save the current document (if necessary) and then runs an + SGML validator. The output from the validator is captured + into a new buffer, and you can then navigate from one + troublespot to the next, fixing markup errors as you + go.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><command>C-c /</command></term> + + <listitem> + <para>Runs <function>sgml-insert-end-tag</function>. Inserts + the end tag for the current open element.</para> + </listitem> + </varlistentry> + </variablelist> + + <para>Doubtless there are other useful functions of this mode, but + those are the ones I use most often.</para> + + <para>You can also use the following entries in + <filename>.emacs</filename> to set proper spacing, indentation, + and column width for working with the Documentation + Project.</para> + + <programlisting> (defun local-sgml-mode-hook + (setq fill-column 70 + indent-tabs-mode nil + next-line-add-newlines nil + standard-indent 4 + sgml-indent-data t) + (auto-fill-mode t) + (setq sgml-catalog-files '("/usr/local/share/xml/catalog"))) + (add-hook 'psgml-mode-hook + '(lambda () (local-psgml-mode-hook)))</programlisting> +</chapter> diff --git a/en_US.ISO8859-1/books/fdp-primer/sgml-markup/chapter.xml b/en_US.ISO8859-1/books/fdp-primer/sgml-markup/chapter.xml new file mode 100644 index 0000000000..6b8f2852c8 --- /dev/null +++ b/en_US.ISO8859-1/books/fdp-primer/sgml-markup/chapter.xml @@ -0,0 +1,2755 @@ +<?xml version="1.0" encoding="iso-8859-1"?> +<!-- Copyright (c) 1998, 1999 Nik Clayton, All rights reserved. + + Redistribution and use in source (SGML DocBook) and 'compiled' forms + (SGML HTML, PDF, PostScript, RTF and so forth) with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code (SGML DocBook) must retain the above + copyright notice, this list of conditions and the following + disclaimer as the first lines of this file unmodified. + + 2. Redistributions in compiled form (transformed to other DTDs, + converted to PDF, PostScript, RTF and other formats) must reproduce + the above copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS DOCUMENTATION IS PROVIDED BY NIK CLAYTON "AS IS" AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL NIK CLAYTON BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS DOCUMENTATION, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + $FreeBSD$ +--> + +<chapter id="xml-markup"> + <title>XML Markup</title> + + <para>This chapter describes the two markup languages you will + encounter when you contribute to the FreeBSD documentation + project. Each section describes the markup language, and details + the markup that you are likely to want to use, or that is already + in use.</para> + + <para>These markup languages contain a large number of elements, and + it can be confusing sometimes to know which element to use for a + particular situation. This section goes through the elements you + are most likely to need, and gives examples of how you would use + them.</para> + + <para>This is <emphasis>not</emphasis> an exhaustive list of + elements, since that would just reiterate the documentation for + each language. The aim of this section is to list those elements + more likely to be useful to you. If you have a question about how + best to markup a particular piece of content, please post it to + the &a.doc;.</para> + + <note> + <title>Inline Versus Block</title> + + <para>In the remainder of this document, when describing elements, + <emphasis>inline</emphasis> means that the element can occur + within a block element, and does not cause a line break. A + <emphasis>block</emphasis> element, by comparison, will cause a + line break (and other processing) when it is encountered.</para> + </note> + + <sect1 id="xml-markup-xhtml"> + <title>XHTML</title> + + <para>XHTML is the XML version of the HyperText Markup Language, + which is the markup language + of choice on the World Wide Web. More information can be found + at <ulink url="http://www.w3.org/"></ulink>.</para> + + <para>XHTML is used to markup pages on the FreeBSD web site. It + should not (generally) be used to mark up other documentation, + since DocBook offers a far richer set of elements to choose + from. Consequently, you will normally only encounter XHTML pages + if you are writing for the web site.</para> + + <para>HTML has gone through a number of versions, 1, 2, 3.0, 3.2, + 4.0 and then an XML-compliant version has also been created, which + is called XHTML and the latest widespread version of it is + XHTML 1.0(available in both + <emphasis>strict</emphasis> and <emphasis>transitional</emphasis> + variants).</para> + + <para>The XHTML DTDs are available from the Ports Collection + in the <filename role="package">textproc/xhtml</filename> port. + They are automatically installed as part of the <filename + role="package">textproc/docproj</filename> port.</para> + + <sect2> + <title>Formal Public Identifier (FPI)</title> + + <para>There are a number of XHTML FPIs, depending upon the + version (also known as the level) of XHTML that you want to + declare your document to be compliant with.</para> + + <para>The majority of XHTML documents on the FreeBSD web site + comply with the transitional version of XHTML 1.0.</para> + + <programlisting>PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"</programlisting> + </sect2> + + <sect2> + <title>Sectional Elements</title> + + <para>An XHTML document is normally split into two sections. The + first section, called the <emphasis>head</emphasis>, contains + meta-information about the document, such as its title, the + name of the author, the parent document, and so on. The + second section, the <emphasis>body</emphasis>, contains the + content that will be displayed to the user.</para> + + <para>These sections are indicated with <sgmltag>head</sgmltag> + and <sgmltag>body</sgmltag> elements respectively. These + elements are contained within the top-level + <sgmltag>html</sgmltag> element.</para> + + <example> + <title>Normal XHTML Document Structure</title> + + <programlisting><html xmlns="http://www.w3.org/1999/xhtml"> + <head> + <title><replaceable>The Document's Title</replaceable></title> + </head> + + <body> + + … + + </body> +</html></programlisting> + </example> + </sect2> + + <sect2> + <title>Block Elements</title> + + <sect3> + <title>Headings</title> + + <para>XHTML allows you to denote headings in your document, at + up to six different levels.</para> + + <para>The largest and most prominent heading is + <sgmltag>h1</sgmltag>, then <sgmltag>h2</sgmltag>, + continuing down to <sgmltag>h6</sgmltag>.</para> + + <para>The element's content is the text of the heading.</para> + + <example> + <title><sgmltag>h1</sgmltag>, <sgmltag>h2</sgmltag>, + and Other Header Tags</title> + + <para>Use:</para> + + <programlisting><h1>First section</h1> + +<!‐- Document introduction goes here -‐> + +<h2>This is the heading for the first section</h2> + +<!‐- Content for the first section goes here -‐> + +<h3>This is the heading for the first sub-section</h3> + +<!‐- Content for the first sub-section goes here -‐> + +<h2>This is the heading for the second section</h2> + +<!‐- Content for the second section goes here -‐></programlisting> + </example> + + <para>Generally, an XHTML page should have one first level + heading (<sgmltag>h1</sgmltag>). This can contain many + second level headings (<sgmltag>h2</sgmltag>), which can in + turn contain many third level headings. Each + <sgmltag>h<replaceable>n</replaceable></sgmltag> element + should have the same element, but one further up the + hierarchy, preceding it. Leaving gaps in the numbering is + to be avoided.</para> + + <example> + <title>Bad Ordering of + <sgmltag>h<replaceable>n</replaceable></sgmltag> + Elements</title> + + <para>Use:</para> + + <programlisting><h1>First section</h1> + +<!‐- Document introduction -‐> + +<h3>Sub-section</h3> + +<!‐- This is bad, <h2> has been left out -‐></programlisting> + </example> + </sect3> + + <sect3> + <title>Paragraphs</title> + + <para>XHTML supports a single paragraph element, + <sgmltag>p</sgmltag>.</para> + + <example> + <title><sgmltag>p</sgmltag></title> + + <para>Use:</para> + + <programlisting><![CDATA[<p>This is a paragraph. It can contain just about any + other element.</p>]]></programlisting> + </example> + </sect3> + + <sect3> + <title>Block Quotations</title> + + <para>A block quotation is an extended quotation from another + document that should not appear within the current + paragraph.</para> + + <example> + <title><sgmltag>blockquote</sgmltag></title> + + <para>Use:</para> + + <programlisting><![CDATA[<p>A small excerpt from the US Constitution:</p> + +<blockquote>We the People of the United States, in Order to form + a more perfect Union, establish Justice, insure domestic + Tranquility, provide for the common defence, promote the general + Welfare, and secure the Blessings of Liberty to ourselves and our + Posterity, do ordain and establish this Constitution for the + United States of America.</blockquote>]]></programlisting> + </example> + </sect3> + + <sect3> + <title>Lists</title> + + <para>You can present the user with three types of lists, + ordered, unordered, and definition.</para> + + <para>Typically, each entry in an ordered list will be + numbered, while each entry in an unordered list will be + preceded by a bullet point. Definition lists are composed + of two sections for each entry. The first section is the + term being defined, and the second section is the definition + of the term.</para> + + <para>Ordered lists are indicated by the <sgmltag>ol</sgmltag> + element, unordered lists by the <sgmltag>ul</sgmltag> + element, and definition lists by the <sgmltag>dl</sgmltag> + element.</para> + + <para>Ordered and unordered lists contain listitems, indicated + by the <sgmltag>li</sgmltag> element. A listitem can + contain textual content, or it may be further wrapped in one + or more <sgmltag>p</sgmltag> elements.</para> + + <para>Definition lists contain definition terms + (<sgmltag>dt</sgmltag>) and definition descriptions + (<sgmltag>dd</sgmltag>). A definition term can only contain + inline elements. A definition description can contain other + block elements.</para> + + <example> + <title><sgmltag>ul</sgmltag> and + <sgmltag>ol</sgmltag></title> + + <para>Use:</para> + + <programlisting><![CDATA[<p>An unordered list. Listitems will probably be + preceded by bullets.</p> + +<ul> + <li>First item</li> + + <li>Second item</li> + + <li>Third item</li> +</ul> + +<p>An ordered list, with list items consisting of multiple + paragraphs. Each item (note: not each paragraph) will be + numbered.</p> + +<ol> + <li><p>This is the first item. It only has one paragraph.</p></li> + + <li><p>This is the first paragraph of the second item.</p> + + <p>This is the second paragraph of the second item.</p></li> + + <li><p>This is the first and only paragraph of the third + item.</p></li> +</ol>]]></programlisting> + </example> + + <example> + <title>Definition Lists with <sgmltag>dl</sgmltag></title> + + <para>Use:</para> + + <programlisting><![CDATA[<dl> + <dt>Term 1</dt> + + <dd><p>Paragraph 1 of definition 1.</p> + + <p>Paragraph 2 of definition 1.</p></dd> + + <dt>Term 2</dt> + + <dd><p>Paragraph 1 of definition 2.</p></dd> + + <dt>Term 3</dt> + + <dd><p>Paragraph 1 of definition 3.</p></dd> +</dl>]]></programlisting> + </example> + </sect3> + + <sect3> + <title>Pre-formatted Text</title> + + <para>You can indicate that text should be shown to the user + exactly as it is in the file. Typically, this means that + the text is shown in a fixed font, multiple spaces are not + merged into one, and line breaks in the text are + significant.</para> + + <para>In order to do this, wrap the content in the + <sgmltag>pre</sgmltag> element.</para> + + <example> + <title><sgmltag>pre</sgmltag></title> + + <para>You could use <sgmltag>pre</sgmltag> to mark up an + email message:</para> + + <programlisting><![CDATA[<pre> From: nik@FreeBSD.org + To: freebsd-doc@FreeBSD.org + Subject: New documentation available + + There is a new copy of my primer for contributors to the FreeBSD + Documentation Project available at + + <URL:http://people.FreeBSD.org/~nik/primer/index.html> + + Comments appreciated. + + N</pre>]]></programlisting> + + <para>Keep in mind that <literal><</literal> and + <literal>&</literal> still are recognized as special + characters in pre-formatted text. This is why the example + shown had to use <literal>&lt;</literal> instead of + <literal><</literal>. For consistency, + <literal>&gt;</literal> was used in place of + <literal>></literal>, too. Watch out for the special + characters that may appear in text copied from a + plain-text source, e.g., an email message or program + code.</para> + </example> + </sect3> + + <sect3> + <title>Tables</title> + + <note> + <para>Most text-mode browsers (such as Lynx) do not render + tables particularly effectively. If you are relying on + the tabular display of your content, you should consider + using alternative markup to prevent confusion.</para> + </note> + + <para>Mark up tabular information using the + <sgmltag>table</sgmltag> element. A table consists of one + or more table rows (<sgmltag>tr</sgmltag>), each containing + one or more cells of table data (<sgmltag>td</sgmltag>). + Each cell can contain other block elements, such as + paragraphs or lists. It can also contain another table + (this nesting can repeat indefinitely). If the cell only + contains one paragraph then you do not need to include the + <sgmltag>p</sgmltag> element.</para> + + <example> + <title>Simple Use of <sgmltag>table</sgmltag></title> + + <para>Use:</para> + + <programlisting><![CDATA[<p>This is a simple 2x2 table.</p> + +<table> + <tr> + <td>Top left cell</td> + + <td>Top right cell</td> + </tr> + + <tr> + <td>Bottom left cell</td> + + <td>Bottom right cell</td> + </tr> +</table>]]></programlisting></example> + + <para>A cell can span multiple rows and columns. To indicate + this, add the <literal>rowspan</literal> and/or + <literal>colspan</literal> attributes, with values + indicating the number of rows or columns that should be + spanned.</para> + + <example> + <title>Using <literal>rowspan</literal></title> + + <para>Use:</para> + + <programlisting><![CDATA[<p>One tall thin cell on the left, two short cells next to + it on the right.</p> + +<table> + <tr> + <td rowspan="2">Long and thin</td> + </tr> + + <tr> + <td>Top cell</td> + + <td>Bottom cell</td> + </tr> +</table>]]></programlisting> + </example> + + <example> + <title>Using <literal>colspan</literal></title> + + <para>Use:</para> + + <programlisting><![CDATA[<p>One long cell on top, two short cells below it.</p> + +<table> + <tr> + <td colspan="2">Top cell</td> + </tr> + + <tr> + <td>Bottom left cell</td> + + <td>Bottom right cell</td> + </tr> +</table>]]></programlisting> + </example> + + <example> + <title>Using <literal>rowspan</literal> and + <literal>colspan</literal> Together</title> + + <para>Use:</para> + + <programlisting><![CDATA[<p>On a 3x3 grid, the top left block is a 2x2 set of + cells merged into one. The other cells are normal.</p> + +<table> + <tr> + <td colspan="2" rowspan="2">Top left large cell</td> + + <td>Top right cell</td> + </tr> + + <tr> + <td>Middle right cell</td> + </tr> + + <tr> + <td>Bottom left cell</td> + + <td>Bottom middle cell</td> + + <td>Bottom right cell</td> + </tr> +</table>]]></programlisting> + </example> + </sect3> + </sect2> + + <sect2> + <title>In-line Elements</title> + + <sect3> + <title>Emphasizing Information</title> + + <para>You have two levels of emphasis available in XHTML, + <sgmltag>em</sgmltag> and <sgmltag>strong</sgmltag>. + <sgmltag>em</sgmltag> is for a normal level of emphasis and + <sgmltag>strong</sgmltag> indicates stronger + emphasis.</para> + + <para>Typically, <sgmltag>em</sgmltag> is rendered in italic + and <sgmltag>strong</sgmltag> is rendered in bold. This is + not always the case, however, and you should not rely on + it. According to best practices, webpages only hold + structural and semantical information and stylesheets are + later applied to use these two so you should think of + semantics not formatting when using these tags.</para> + + <example> + <title><sgmltag>em</sgmltag> and + <sgmltag>strong</sgmltag></title> + + <para>Use:</para> + + <programlisting><![CDATA[<p><em>This</em> has been emphasized, while + <strong>this</strong> has been strongly emphasized.</p>]]></programlisting> + </example> + </sect3> + + <sect3> + <title>Indicating Fixed-Pitch Text</title> + + <para>If you have content that should be rendered in a fixed + pitch (typewriter) typeface, use <sgmltag>tt</sgmltag> (for + <quote>teletype</quote>).</para> + + <example> + <title><sgmltag>tt</sgmltag></title> + + <para>Use:</para> + + <programlisting><![CDATA[<p>This document was originally written by + Nik Clayton, who can be reached by email as + <tt>nik@FreeBSD.org</tt>.</p>]]></programlisting> + </example> + </sect3> + </sect2> + + <sect2> + <title>Links</title> + + <note> + <para>Links are also inline elements.</para> + </note> + + <sect3> + <title>Linking to Other Documents on the WWW</title> + + <para>In order to include a link to another document on the + WWW you must know the URL of the document you want to link + to.</para> + + <para>The link is indicated with <sgmltag>a</sgmltag>, and the + <literal>href</literal> attribute contains the URL of the + target document. The content of the element becomes the + link, and is normally indicated to the user in some way + (underlining, change of color, different mouse cursor when + over the link, and so on).</para> + + <example> + <title>Using <literal><a href="..."></literal></title> + + <para>Use:</para> + + <programlisting><![CDATA[<p>More information is available at the + <a href="http://www.FreeBSD.org/">FreeBSD web site</a>.</p>]]></programlisting> + </example> + + <para>These links will take the user to the top of the chosen + document.</para> + </sect3> + + <sect3> + <title>Linking to Other Parts of Documents</title> + + <para>Linking to a point within another document (or within + the same document) requires that the document author include + anchors that you can link to.</para> + + <para>Anchors are indicated with <sgmltag>a</sgmltag> and the + <literal>id</literal> attribute instead of + <literal>href</literal>.</para> + + <example> + <title>Using <literal><a id="..."></literal></title> + + <para>Use:</para> + + <programlisting><![CDATA[<p><a id="para1">This</a> paragraph can be referenced + in other links with the name <tt>para1</tt>.</p>]]></programlisting> + </example> + + <para>To link to a named part of a document, write a normal + link to that document, but include the id of the anchor + after a <literal>#</literal> symbol.</para> + + <example> + <title>Linking to a Named Part of Another Document</title> + + <para>Assume that the <literal>para1</literal> example + resides in a document called + <filename>foo.html</filename>.</para> + + <programlisting><![CDATA[<p>More information can be found in the + <a href="foo.html#para1">first paragraph</a> of + <tt>foo.html</tt>.</p>]]></programlisting> + </example> + + <para>If you are linking to a named anchor within the same + document then you can omit the document's URL, and just + include the name of the anchor (with the preceding + <literal>#</literal>).</para> + + <example> + <title>Linking to a Named Part of the Same Document</title> + + <para>Assume that the <literal>para1</literal> example + resides in this document:</para> + + <programlisting><![CDATA[<p>More information can be found in the + <a href="#para1">first paragraph</a> of this + document.</p>]]></programlisting> + </example> + </sect3> + </sect2> + </sect1> + + <sect1 id="xml-markup-docbook"> + <title>DocBook</title> + + <para>DocBook was originally developed by HaL Computer Systems and + O'Reilly & Associates to be a DTD for writing technical + documentation <footnote><para>A short history can be found under + <ulink + url="http://www.oasis-open.org/docbook/intro.shtml#d0e41"> + http://www.oasis-open.org/docbook/intro.shtml#d0e41</ulink>.</para></footnote>. + Since 1998 it is maintained by the <ulink + url="http://www.oasis-open.org/committees/tc_home.php?wg_abbrev=docbook"> + DocBook Technical Committee</ulink>. As such, and unlike + LinuxDoc and XHTML, DocBook is very heavily oriented towards + markup that describes <emphasis>what</emphasis> something is, + rather than describing <emphasis>how</emphasis> it should be + presented.</para> + + <note> + <title>Formal Versus Informal</title> + + <para>Some elements may exist in two forms, + <emphasis>formal</emphasis> and <emphasis>informal</emphasis>. + Typically, the formal version of the element will consist of a + title followed by the informal version of the element. The + informal version will not have a title.</para> + </note> + + <para>The DocBook DTD is available from the Ports Collection + in the <filename role="package">textproc/docbook-xml-450</filename> + port. It is automatically installed as part of the <filename + role="package">textproc/docproj</filename> port.</para> + + <sect2> + <title>&os; Extensions</title> + + <para>The FreeBSD Documentation Project has extended the DocBook + DTD by adding some new elements. These elements serve to make + some of the markup more precise.</para> + + <para>Where a FreeBSD specific element is listed below it is + clearly marked.</para> + + <para>Throughout the rest of this document, the term + <quote>DocBook</quote> is used to mean the FreeBSD extended + DocBook DTD.</para> + + <note> + <para>There is nothing about these extensions that is FreeBSD + specific, it was just felt that they were useful + enhancements for this particular project. Should anyone + from any of the other *nix camps (NetBSD, OpenBSD, Linux, + …) be interested in collaborating on a standard + DocBook extension set, please get in touch with + &a.doceng;.</para> + </note> + + <para>The &os; extensions are not (currently) in the + Ports Collection. They are stored in the &os; Subversion + tree, as <ulink + url="http://svnweb.FreeBSD.org/doc/head/share/xml/freebsd.dtd">head/share/xml/freebsd.dtd</ulink>.</para> + </sect2> + + <sect2> + <title>Formal Public Identifier (FPI)</title> + + <para>In compliance with the DocBook guidelines for writing FPIs + for DocBook customizations, the FPI for the FreeBSD extended + DocBook DTD is:</para> + + <programlisting>PUBLIC "-//FreeBSD//DTD DocBook V4.2-Based Extension//EN"</programlisting> + </sect2> + + <sect2> + <title>Document Structure</title> + + <para>DocBook allows you to structure your documentation in + several ways. In the FreeBSD Documentation Project we are + using two primary types of DocBook document: the book and the + article.</para> + + <para>A book is organized into <sgmltag>chapter</sgmltag>s. + This is a mandatory requirement. There may be + <sgmltag>part</sgmltag>s between the book and the chapter to + provide another layer of organization. For example, the + Handbook is arranged in this way.</para> + + <para>A chapter may (or may not) contain one or more sections. + These are indicated with the <sgmltag>sect1</sgmltag> element. + If a section contains another section then use the + <sgmltag>sect2</sgmltag> element, and so on, up to + <sgmltag>sect5</sgmltag>.</para> + + <para>Chapters and sections contain the remainder of the + content.</para> + + <para>An article is simpler than a book, and does not use + chapters. Instead, the content of an article is organized + into one or more sections, using the same + <sgmltag>sect1</sgmltag> (and <sgmltag>sect2</sgmltag> and so + on) elements that are used in books.</para> + + <para>Obviously, you should consider the nature of the + documentation you are writing in order to decide whether it is + best marked up as a book or an article. Articles are well + suited to information that does not need to be broken down + into several chapters, and that is, relatively speaking, quite + short, at up to 20-25 pages of content. Books are best suited + to information that can be broken up into several chapters, + possibly with appendices and similar content as well.</para> + + <para>The <ulink url="&url.base;/docs.html">FreeBSD + tutorials</ulink> are all marked up as articles, while this + document, the + <ulink url="&url.books.faq;/index.html">FreeBSD FAQ</ulink>, + and the <ulink url="&url.books.handbook;/index.html">FreeBSD + Handbook</ulink> are all marked up as books, for + example.</para> + + <sect3> + <title>Starting a Book</title> + + <para>The content of the book is contained within the + <sgmltag>book</sgmltag> element. As well as containing + structural markup, this element can contain elements that + include additional information about the book. This is + either meta-information, used for reference purposes, or + additional content used to produce a title page.</para> + + <para>This additional information should be contained within + <sgmltag>bookinfo</sgmltag>.</para> + + <example> + <title>Boilerplate <sgmltag>book</sgmltag> with + <sgmltag>bookinfo</sgmltag></title> + + <!-- Can't put this in a marked section because of the + replaceable elements --> + + <programlisting><book> + <bookinfo> + <title><replaceable>Your Title Here</replaceable></title> + + <author> + <firstname><replaceable>Your first name</replaceable></firstname> + <surname><replaceable>Your surname</replaceable></surname> + <affiliation> + <address><email><replaceable>Your email address</replaceable></email></address> + </affiliation> + </author> + + <copyright> + <year><replaceable>1998</replaceable></year> + <holder role="mailto:<replaceable>your email address</replaceable>"><replaceable>Your name</replaceable></holder> + </copyright> + + <releaseinfo>$FreeBSD$</releaseinfo> + + <abstract> + <para><replaceable>Include an abstract of the book's contents here.</replaceable></para> + </abstract> + </bookinfo> + + … + +</book></programlisting> + </example> + </sect3> + + <sect3> + <title>Starting an Article</title> + + <para>The content of the article is contained within the + <sgmltag>article</sgmltag> element. As well as containing + structural markup, this element can contain elements that + include additional information about the article. This is + either meta-information, used for reference purposes, or + additional content used to produce a title page.</para> + + <para>This additional information should be contained within + <sgmltag>articleinfo</sgmltag>.</para> + + <example> + <title>Boilerplate <sgmltag>article</sgmltag> with + <sgmltag>articleinfo</sgmltag></title> + + <!-- Can't put this in a marked section because of the + replaceable elements --> + + <programlisting><article> + <articleinfo> + <title><replaceable>Your title here</replaceable></title> + + <author> + <firstname><replaceable>Your first name</replaceable></firstname> + <surname><replaceable>Your surname</replaceable></surname> + <affiliation> + <address><email><replaceable>Your email address</replaceable></email></address> + </affiliation> + </author> + + <copyright> + <year><replaceable>1998</replaceable></year> + <holder role="mailto:<replaceable>your email address</replaceable>"><replaceable>Your name</replaceable></holder> + </copyright> + + <releaseinfo>$FreeBSD$</releaseinfo> + + <abstract> + <para><replaceable>Include an abstract of the article's contents here.</replaceable></para> + </abstract> + </articleinfo> + + … + +</article></programlisting> + </example> + </sect3> + + <sect3> + <title>Indicating Chapters</title> + + <para>Use <sgmltag>chapter</sgmltag> to mark up your chapters. + Each chapter has a mandatory <sgmltag>title</sgmltag>. + Articles do not contain chapters, they are reserved for + books.</para> + + <example> + <title>A Simple Chapter</title> + + <programlisting><![CDATA[<chapter> + <title>The Chapter's Title</title> + + ... +</chapter>]]></programlisting> + </example> + + <para>A chapter cannot be empty; it must contain elements in + addition to <sgmltag>title</sgmltag>. If you need to + include an empty chapter then just use an empty + paragraph.</para> + + <example> + <title>Empty Chapters</title> + + <programlisting><![CDATA[<chapter> + <title>This is An Empty Chapter</title> + + <para></para> +</chapter>]]></programlisting> + </example> + </sect3> + + <sect3> + <title>Sections Below Chapters</title> + + <para>In books, chapters may (but do not need to) be broken up + into sections, subsections, and so on. In articles, + sections are the main structural element, and each article + must contain at least one section. Use the + <sgmltag>sect<replaceable>n</replaceable></sgmltag> element. + The <replaceable>n</replaceable> indicates the section + number, which identifies the section level.</para> + + <para>The first + <sgmltag>sect<replaceable>n</replaceable></sgmltag> is + <sgmltag>sect1</sgmltag>. You can have one or more of these + in a chapter. They can contain one or more + <sgmltag>sect2</sgmltag> elements, and so on, down to + <sgmltag>sect5</sgmltag>.</para> + + <example> + <title>Sections in Chapters</title> + + <programlisting><![CDATA[<chapter> + <title>A Sample Chapter</title> + + <para>Some text in the chapter.</para> + + <sect1> + <title>First Section (1.1)</title> + + … + </sect1> + + <sect1> + <title>Second Section (1.2)</title> + + <sect2> + <title>First Sub-Section (1.2.1)</title> + + <sect3> + <title>First Sub-Sub-Section (1.2.1.1)</title> + + … + </sect3> + </sect2> + + <sect2> + <title>Second Sub-Section (1.2.2)</title> + + … + </sect2> + </sect1> +</chapter>]]></programlisting> + </example> + + <note> + <para>This example includes section numbers in the section + titles. You should not do this in your documents. Adding + the section numbers is carried out by the stylesheets (of + which more later), and you do not need to manage them + yourself.</para> + </note> + </sect3> + + <sect3> + <title>Subdividing Using <sgmltag>part</sgmltag> + Elements</title> + + <para>You can introduce another layer of organization between + <sgmltag>book</sgmltag> and <sgmltag>chapter</sgmltag> with + one or more <sgmltag>part</sgmltag>s. This cannot be done + in an <sgmltag>article</sgmltag>.</para> + + <programlisting><![CDATA[<part> + <title>Introduction</title> + + <chapter> + <title>Overview</title> + + ... + </chapter> + + <chapter> + <title>What is FreeBSD?</title> + + ... + </chapter> + + <chapter> + <title>History</title> + + ... + </chapter> +</part>]]></programlisting> + </sect3> + </sect2> + + <sect2> + <title>Block Elements</title> + + <sect3> + <title>Paragraphs</title> + + <para>DocBook supports three types of paragraphs: + <sgmltag>formalpara</sgmltag>, <sgmltag>para</sgmltag>, and + <sgmltag>simpara</sgmltag>.</para> + + <para>Most of the time you will only need to use + <sgmltag>para</sgmltag>. <sgmltag>formalpara</sgmltag> + includes a <sgmltag>title</sgmltag> element, and + <sgmltag>simpara</sgmltag> disallows some elements from + within <sgmltag>para</sgmltag>. Stick with + <sgmltag>para</sgmltag>.</para> + + <example> + <title><sgmltag>para</sgmltag></title> + + <para>Use:</para> + + <programlisting><![CDATA[<para>This is a paragraph. It can contain just about any + other element.</para> ]]></programlisting> + + <para>Appearance:</para> + + <para>This is a paragraph. It can contain just about any + other element.</para> + </example> + </sect3> + + <sect3> + <title>Block Quotations</title> + + <para>A block quotation is an extended quotation from another + document that should not appear within the current + paragraph. You will probably only need it + infrequently.</para> + + <para>Blockquotes can optionally contain a title and an + attribution (or they can be left untitled and + unattributed).</para> + + <example> + <title><sgmltag>blockquote</sgmltag></title> + + <para>Use:</para> + + <programlisting><![CDATA[<para>A small excerpt from the US Constitution:</para> + +<blockquote> + <title>Preamble to the Constitution of the United States</title> + + <attribution>Copied from a web site somewhere</attribution> + + <para>We the People of the United States, in Order to form a more perfect + Union, establish Justice, insure domestic Tranquility, provide for the + common defence, promote the general Welfare, and secure the Blessings + of Liberty to ourselves and our Posterity, do ordain and establish this + Constitution for the United States of America.</para> +</blockquote>]]></programlisting> + + <para>Appearance:</para> + + <para>A small excerpt from the US Constitution:</para> + + <blockquote> + <title>Preamble to the Constitution of the United + States</title> + + <attribution>Copied from a web site + somewhere</attribution> + + <para>We the People of the United States, in Order to form + a more perfect Union, establish Justice, insure domestic + Tranquility, provide for the common defence, promote the + general Welfare, and secure the Blessings of Liberty to + ourselves and our Posterity, do ordain and establish + this Constitution for the United States of + America.</para> + </blockquote> + </example> + </sect3> + + <sect3> + <title>Tips, Notes, Warnings, Cautions, Important Information + and Sidebars</title> + + <para>You may need to include extra information separate from + the main body of the text. Typically this is + <quote>meta</quote> information that the user should be + aware of.</para> + + <para>Depending on the nature of the information, one of + <sgmltag>tip</sgmltag>, <sgmltag>note</sgmltag>, + <sgmltag>warning</sgmltag>, <sgmltag>caution</sgmltag>, and + <sgmltag>important</sgmltag> should be used. Alternatively, + if the information is related to the main text but is not + one of the above, use <sgmltag>sidebar</sgmltag>.</para> + + <para>The circumstances in which to choose one of these + elements over another is unclear. The DocBook documentation + suggests:</para> + + <itemizedlist> + <listitem> + <para>A Note is for information that should be heeded by + all readers.</para> + </listitem> + + <listitem> + <para>An Important element is a variation on Note.</para> + </listitem> + + <listitem> + <para>A Caution is for information regarding possible data + loss or software damage.</para> + </listitem> + + <listitem> + <para>A Warning is for information regarding possible + hardware damage or injury to life or limb.</para> + </listitem> + </itemizedlist> + + <example> + <title><sgmltag>warning</sgmltag></title> + + <para>Use:</para> + + <programlisting><![CDATA[<warning> + <para>Installing FreeBSD may make you want to delete Windows from your + hard disk.</para> +</warning>]]></programlisting> + </example> + + <para>Appearance:</para> + <!-- Need to do this outside of the example --> + <warning> + <para>Installing FreeBSD may make you want to delete Windows + from your hard disk.</para> + </warning> + </sect3> + + <sect3> + <title>Lists and Procedures</title> + + <para>You will often need to list pieces of information to the + user, or present them with a number of steps that must be + carried out in order to accomplish a particular goal.</para> + + <para>In order to do this, use + <sgmltag>itemizedlist</sgmltag>, + <sgmltag>orderedlist</sgmltag>, or + <sgmltag>procedure</sgmltag><footnote><para>There are other + types of list element in DocBook, but we are not + concerned with those at the + moment.</para></footnote></para> + + <para><sgmltag>itemizedlist</sgmltag> and + <sgmltag>orderedlist</sgmltag> are similar to their + counterparts in HTML, <sgmltag>ul</sgmltag> and + <sgmltag>ol</sgmltag>. Each one consists of one or more + <sgmltag>listitem</sgmltag> elements, and each + <sgmltag>listitem</sgmltag> contains one or more block + elements. The <sgmltag>listitem</sgmltag> elements are + analogous to HTML's <sgmltag>li</sgmltag> tags. However, + unlike HTML, they are required.</para> + + <para><sgmltag>procedure</sgmltag> is slightly different. It + consists of <sgmltag>step</sgmltag>s, which may in turn + consists of more <sgmltag>step</sgmltag>s or + <sgmltag>substep</sgmltag>s. Each <sgmltag>step</sgmltag> + contains block elements.</para> + + <example> + <title><sgmltag>itemizedlist</sgmltag>, + <sgmltag>orderedlist</sgmltag>, and + <sgmltag>procedure</sgmltag></title> + + <para>Use:</para> + + <programlisting><![CDATA[<itemizedlist> + <listitem> + <para>This is the first itemized item.</para> + </listitem> + + <listitem> + <para>This is the second itemized item.</para> + </listitem> +</itemizedlist> + +<orderedlist> + <listitem> + <para>This is the first ordered item.</para> + </listitem> + + <listitem> + <para>This is the second ordered item.</para> + </listitem> +</orderedlist> + +<procedure> + <step> + <para>Do this.</para> + </step> + + <step> + <para>Then do this.</para> + </step> + + <step> + <para>And now do this.</para> + </step> +</procedure>]]></programlisting> + + <para>Appearance:</para> + + <itemizedlist> + <listitem> + <para>This is the first itemized item.</para> + </listitem> + + <listitem> + <para>This is the second itemized item.</para> + </listitem> + </itemizedlist> + + <orderedlist> + <listitem> + <para>This is the first ordered item.</para> + </listitem> + + <listitem> + <para>This is the second ordered item.</para> + </listitem> + </orderedlist> + </example> + + <!-- Can't have <procedure> inside <example>, so this is a cheat --> + + <procedure> + <step> + <para>Do this.</para> + </step> + + <step> + <para>Then do this.</para> + </step> + + <step> + <para>And now do this.</para> + </step> + </procedure> + </sect3> + + <sect3> + <title>Showing File Samples</title> + + <para>If you want to show a fragment of a file (or perhaps a + complete file) to the user, wrap it in the + <sgmltag>programlisting</sgmltag> element.</para> + + <para>White space and line breaks within + <sgmltag>programlisting</sgmltag> <emphasis>are</emphasis> + significant. In particular, this means that the opening tag + should appear on the same line as the first line of the + output, and the closing tag should appear on the same line + as the last line of the output, otherwise spurious blank + lines may be included.</para> + + <example> + <title><sgmltag>programlisting</sgmltag></title> + + <para>Use:</para> + + <programlisting><![CDATA[<para>When you have finished, your program should look like + this:</para> + +<programlisting>#include <stdio.h> + +int +main(void) +{ + printf("hello, world\n"); +}</programlisting>]]></programlisting> + + <para>Notice how the angle brackets in the + <literal>#include</literal> line need to be referenced by + their entities instead of being included literally.</para> + + <para>Appearance:</para> + + <para>When you have finished, your program should look like + this:</para> + + <programlisting>#include <stdio.h> + +int +main(void) +{ + printf("hello, world\n"); +}</programlisting> + </example> + </sect3> + + <sect3> + <title>Callouts</title> + + <para>A callout is a mechanism for referring back to an + earlier piece of text or specific position within an earlier + example without linking to it within the text.</para> + + <para>To do this, mark areas of interest in your example + (<sgmltag>programlisting</sgmltag>, + <sgmltag>literallayout</sgmltag>, or whatever) with the + <sgmltag>co</sgmltag> element. Each element must have a + unique <literal>id</literal> assigned to it. After the + example include a <sgmltag>calloutlist</sgmltag> that refers + back to the example and provides additional + commentary.</para> + + <example> + <title><sgmltag>co</sgmltag> and + <sgmltag>calloutlist</sgmltag></title> + + <programlisting><![CDATA[<para>When you have finished, your program should look like + this:</para> + +<programlisting>#include <stdio.h> <co id="co-ex-include"/> + +int <co id="co-ex-return"/> +main(void) +{ + printf("hello, world\n"); <co id="co-ex-printf"/> +}</programlisting> + +<calloutlist> + <callout arearefs="co-ex-include"> + <para>Includes the standard IO header file.</para> + </callout> + + <callout arearefs="co-ex-return"> + <para>Specifies that <function>main()</function> returns an + int.</para> + </callout> + + <callout arearefs="co-ex-printf"> + <para>The <function>printf()</function> call that writes + <literal>hello, world</literal> to standard output.</para> + </callout> +</calloutlist>]]></programlisting> + + <para>Appearance:</para> + + <para>When you have finished, your program should look like + this:</para> + + <programlisting>#include <stdio.h> <co id="co-ex-include"/> + +int <co id="co-ex-return"/> +main(void) +{ + printf("hello, world\n"); <co id="co-ex-printf"/> +}</programlisting> + + <calloutlist> + <callout arearefs="co-ex-include"> + <para>Includes the standard IO header file.</para> + </callout> + + <callout arearefs="co-ex-return"> + <para>Specifies that <function>main()</function> returns + an int.</para> + </callout> + + <callout arearefs="co-ex-printf"> + <para>The <function>printf()</function> call that writes + <literal>hello, world</literal> to standard + output.</para> + </callout> + </calloutlist> + </example> + </sect3> + + <sect3> + <title>Tables</title> + + <para>Unlike HTML, you do not need to use tables for layout + purposes, as the stylesheet handles those issues for you. + Instead, just use tables for marking up tabular data.</para> + + <para>In general terms (and see the DocBook documentation for + more detail) a table (which can be either formal or + informal) consists of a <sgmltag>table</sgmltag> element. + This contains at least one <sgmltag>tgroup</sgmltag> + element, which specifies (as an attribute) the number of + columns in this table group. Within the tablegroup you can + then have one <sgmltag>thead</sgmltag> element, which + contains elements for the table headings (column headings), + and one <sgmltag>tbody</sgmltag> which contains the body of + the table.</para> + + <para>Both <sgmltag>tgroup</sgmltag> and + <sgmltag>thead</sgmltag> contain <sgmltag>row</sgmltag> + elements, which in turn contain <sgmltag>entry</sgmltag> + elements. Each <sgmltag>entry</sgmltag> element specifies + one cell in the table.</para> + + <example> + <title><sgmltag>informaltable</sgmltag></title> + + <para>Use:</para> + + <programlisting><![CDATA[<informaltable pgwide="1"> + <tgroup cols="2"> + <thead> + <row> + <entry>This is Column Head 1</entry> + <entry>This is Column Head 2</entry> + </row> + </thead> + + <tbody> + <row> + <entry>Row 1, column 1</entry> + <entry>Row 1, column 2</entry> + </row> + + <row> + <entry>Row 2, column 1</entry> + <entry>Row 2, column 2</entry> + </row> + </tbody> + </tgroup> +</informaltable>]]></programlisting> + + <para>Appearance:</para> + + <informaltable pgwide="1"> + <tgroup cols="2"> + <thead> + <row> + <entry>This is Column Head 1</entry> + <entry>This is Column Head 2</entry> + </row> + </thead> + + <tbody> + <row> + <entry>Row 1, column 1</entry> + <entry>Row 1, column 2</entry> + </row> + + <row> + <entry>Row 2, column 1</entry> + <entry>Row 2, column 2</entry> + </row> + </tbody> + </tgroup> + </informaltable> + </example> + + <para>Always use the <literal>pgwide</literal> attribute with + a value of <literal>1</literal> with the + <sgmltag>informaltable</sgmltag> element. A bug in Internet + Explorer can cause the table to render incorrectly if this + is omitted.</para> + + <para>If you do not want a border around the table the + <literal>frame</literal> attribute can be added to the + <sgmltag>informaltable</sgmltag> element with a value of + <literal>none</literal> (i.e., <literal><informaltable + frame="none"></literal>).</para> + + <example> + <title>Tables Where <literal>frame="none"</literal></title> + + <para>Appearance:</para> + + <informaltable frame="none" pgwide="1"> + <tgroup cols="2"> + <thead> + <row> + <entry>This is Column Head 1</entry> + <entry>This is Column Head 2</entry> + </row> + </thead> + + <tbody> + <row> + <entry>Row 1, column 1</entry> + <entry>Row 1, column 2</entry> + </row> + + <row> + <entry>Row 2, column 1</entry> + <entry>Row 2, column 2</entry> + </row> + </tbody> + </tgroup> + </informaltable> + </example> + </sect3> + + <sect3> + <title>Examples for the User to Follow</title> + + <para>A lot of the time you need to show examples for the user + to follow. Typically, these will consist of dialogs with + the computer; the user types in a command, the user gets a + response back, they type in another command, and so + on.</para> + + <para>A number of distinct elements and entities come into + play here.</para> + + <variablelist> + <varlistentry> + <term><sgmltag>screen</sgmltag></term> + + <listitem> + <para>Everything the user sees in this example will be + on the computer screen, so the next element is + <sgmltag>screen</sgmltag>.</para> + + <para>Within <sgmltag>screen</sgmltag>, white space is + significant.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><sgmltag>prompt</sgmltag>, + <literal>&prompt.root;</literal> and + <literal>&prompt.user;</literal></term> + + <listitem> + <para>Some of the things the user will be seeing on the + screen are prompts from the computer (either from the + operating system, command shell, or application). + These should be marked up using + <sgmltag>prompt</sgmltag>.</para> + + <para>As a special case, the two shell prompts for the + normal user and the root user have been provided as + entities. Every time you want to indicate the user is + at a shell prompt, use one of + <literal>&prompt.root;</literal> and + <literal>&prompt.user;</literal> as necessary. + They do not need to be inside + <sgmltag>prompt</sgmltag>.</para> + + <note> + <para><literal>&prompt.root;</literal> and + <literal>&prompt.user;</literal> are FreeBSD + extensions to DocBook, and are not part of the + original DTD.</para> + </note> + </listitem> + </varlistentry> + + <varlistentry> + <term><sgmltag>userinput</sgmltag></term> + + <listitem> + <para>When displaying text that the user should type in, + wrap it in <sgmltag>userinput</sgmltag> tags. It will + probably be displayed differently to the user.</para> + </listitem> + </varlistentry> + </variablelist> + + <example> + <title><sgmltag>screen</sgmltag>, <sgmltag>prompt</sgmltag>, + and <sgmltag>userinput</sgmltag></title> + + <para>Use:</para> + + <programlisting><![CDATA[<screen>&prompt.user; <userinput>ls -1</userinput> +foo1 +foo2 +foo3 +&prompt.user; <userinput>ls -1 | grep foo2</userinput> +foo2 +&prompt.user; <userinput>su</userinput> +<prompt>Password: </prompt> +&prompt.root; <userinput>cat foo2</userinput> +This is the file called 'foo2'</screen>]]></programlisting> + + <para>Appearance:</para> + + <screen>&prompt.user; <userinput>ls -1</userinput> +foo1 +foo2 +foo3 +&prompt.user; <userinput>ls -1 | grep foo2</userinput> +foo2 +&prompt.user; <userinput>su</userinput> +<prompt>Password: </prompt> +&prompt.root; <userinput>cat foo2</userinput> +This is the file called 'foo2'</screen> + </example> + + <note> + <para>Even though we are displaying the contents of the file + <filename>foo2</filename>, it is <emphasis>not</emphasis> + marked up as <sgmltag>programlisting</sgmltag>. Reserve + <sgmltag>programlisting</sgmltag> for showing fragments of + files outside the context of user actions.</para> + </note> + </sect3> + </sect2> + + <sect2> + <title>In-line Elements</title> + + <sect3> + <title>Emphasizing Information</title> + + <para>When you want to emphasize a particular word or phrase, + use <sgmltag>emphasis</sgmltag>. This may be presented as + italic, or bold, or might be spoken differently with a + text-to-speech system.</para> + + <para>There is no way to change the presentation of the + emphasis within your document, no equivalent of HTML's + <sgmltag>b</sgmltag> and <sgmltag>i</sgmltag>. If the + information you are presenting is important then consider + presenting it in <sgmltag>important</sgmltag> rather than + <sgmltag>emphasis</sgmltag>.</para> + + <example> + <title><sgmltag>emphasis</sgmltag></title> + + <para>Use:</para> + + <programlisting><![CDATA[<para>FreeBSD is without doubt <emphasis>the</emphasis> + premiere Unix like operating system for the Intel architecture.</para>]]></programlisting> + + <para>Appearance:</para> + + <para>FreeBSD is without doubt <emphasis>the</emphasis> + premiere Unix like operating system for the Intel + architecture.</para> + </example> + </sect3> + + <sect3> + <title>Quotations</title> + + <para>To quote text from another document or source, or to + denote a phrase that is used figuratively, use + <sgmltag>quote</sgmltag>. Within a <sgmltag>quote</sgmltag> + tag, you may use most of the markup tags available for + normal text.</para> + + <example> + <title>Quotations</title> + + <para>Use:</para> + + <programlisting><![CDATA[<para>However, make sure that the search does not go beyond the + <quote>boundary between local and public administration</quote>, + as RFC 1535 calls it.</para>]]></programlisting> + + <para>Appearance:</para> + + <para>However, make sure that the search does not go beyond + the <quote>boundary between local and public + administration</quote>, as RFC 1535 calls it.</para> + </example> + </sect3> + + <sect3> + <title>Keys, Mouse Buttons, and Combinations</title> + + <para>To refer to a specific key on the keyboard, use + <sgmltag>keycap</sgmltag>. To refer to a mouse button, use + <sgmltag>mousebutton</sgmltag>. And to refer to + combinations of key presses or mouse clicks, wrap them all + in <sgmltag>keycombo</sgmltag>.</para> + + <para><sgmltag>keycombo</sgmltag> has an attribute called + <literal>action</literal>, which may be one of + <literal>click</literal>, <literal>double-click</literal>, + <literal>other</literal>, <literal>press</literal>, + <literal>seq</literal>, or <literal>simul</literal>. The + last two values denote whether the keys or buttons should be + pressed in sequence, or simultaneously.</para> + + <para>The stylesheets automatically add any connecting + symbols, such as <literal>+</literal>, between the key + names, when wrapped in <sgmltag>keycombo</sgmltag>.</para> + + <example> + <title>Keys, Mouse Buttons, and Combinations</title> + + <para>Use:</para> + + <programlisting><![CDATA[<para>To switch to the second virtual terminal, press + <keycombo action="simul"><keycap>Alt</keycap> + <keycap>F1</keycap></keycombo>.</para> + +<para>To exit <command>vi</command> without saving your work, type + <keycombo action="seq"><keycap>Esc</keycap><keycap>:</keycap> + <keycap>q</keycap><keycap>!</keycap></keycombo>.</para> + +<para>My window manager is configured so that + <keycombo action="simul"><keycap>Alt</keycap> + <mousebutton>right</mousebutton> + </keycombo> mouse button is used to move windows.</para>]]></programlisting> + + <para>Appearance:</para> + + <para>To switch to the second virtual terminal, press + <keycombo action="simul"><keycap>Alt</keycap> + <keycap>F1</keycap></keycombo>.</para> + + <para>To exit <command>vi</command> without saving your + work, type <keycombo action="seq"> + <keycap>Esc</keycap> + <keycap>:</keycap> + <keycap>q</keycap> + <keycap>!</keycap></keycombo>.</para> + + <para>My window manager is configured so that + <keycombo action="simul"> + <keycap>Alt</keycap> + <mousebutton>right</mousebutton></keycombo> mouse button + is used to move windows.</para> + </example> + </sect3> + + <sect3> + <title>Applications, Commands, Options, and Cites</title> + + <para>You will frequently want to refer to both applications + and commands when writing documentation. The distinction + between them is simple: an application is the name for a + suite (or possibly just 1) of programs that fulfill a + particular task. A command is the name of a program that + the user can run.</para> + + <para>In addition, you will occasionally need to list one or + more of the options that a command might take.</para> + + <para>Finally, you will often want to list a command with its + manual section number, in the <quote>command(number)</quote> + format so common in Unix manuals.</para> + + <para>Mark up application names with + <sgmltag>application</sgmltag>.</para> + + <para>When you want to list a command with its manual section + number (which should be most of the time) the DocBook + element is <sgmltag>citerefentry</sgmltag>. This will + contain a further two elements, + <sgmltag>refentrytitle</sgmltag> and + <sgmltag>manvolnum</sgmltag>. The content of + <sgmltag>refentrytitle</sgmltag> is the name of the command, + and the content of <sgmltag>manvolnum</sgmltag> is the + manual page section.</para> + + <para>This can be cumbersome to write, and so a series of + <link linkend="xml-primer-general-entities">general + entities</link> have been created to make this easier. + Each entity takes the form + <literal>&man.<replaceable>manual-page</replaceable>.<replaceable>manual-section</replaceable>;</literal>.</para> + + <para>The file that contains these entities is in + <filename>doc/share/xml/man-refs.ent</filename>, and can be + referred to using this FPI:</para> + + <programlisting>PUBLIC "-//FreeBSD//ENTITIES DocBook Manual Page Entities//EN"</programlisting> + + <para>Therefore, the introduction to your documentation will + probably look like this:</para> + + <programlisting><!DOCTYPE book PUBLIC "-//FreeBSD//DTD DocBook V4.1-Based Extension//EN" [ + +<!ENTITY % man PUBLIC "-//FreeBSD//ENTITIES DocBook Manual Page Entities//EN"> +%man; + +… + +]></programlisting> + + <para>Use <sgmltag>command</sgmltag> when you want to include + a command name <quote>in-line</quote> but present it as + something the user should type in.</para> + + <para>Use <sgmltag>option</sgmltag> to mark up the options + which will be passed to a command.</para> + + <para>When referring to the same command multiple times in + close proximity it is preferred to use the + <literal>&man.<replaceable>command</replaceable>.<replaceable>section</replaceable>;</literal> + notation to markup the first reference and use + <sgmltag>command</sgmltag> to markup subsequent references. + This makes the generated output, especially HTML, appear + visually better.</para> + + <para>This can be confusing, and sometimes the choice is not + always clear. Hopefully this example makes it + clearer.</para> + + <example> + <title>Applications, Commands, and Options</title> + + <para>Use:</para> + + <programlisting><![CDATA[<para><application>Sendmail</application> is the most + widely used Unix mail application.</para> + +<para><application>Sendmail</application> includes the + <citerefentry> + <refentrytitle>sendmail</refentrytitle> + <manvolnum>8</manvolnum> + </citerefentry>, &man.mailq.1;, and &man.newaliases.1; + programs.</para> + +<para>One of the command line parameters to <citerefentry> + <refentrytitle>sendmail</refentrytitle> + <manvolnum>8</manvolnum> + </citerefentry>, <option>-bp</option>, will display the current + status of messages in the mail queue. Check this on the command + line by running <command>sendmail -bp</command>.</para>]]></programlisting> + + <para>Appearance:</para> + + <para><application>Sendmail</application> is the most widely + used Unix mail application.</para> + + <para><application>Sendmail</application> includes the + <citerefentry> + <refentrytitle>sendmail</refentrytitle> + <manvolnum>8</manvolnum> + </citerefentry>, &man.mailq.1;, and &man.newaliases.1; + programs.</para> + + <para>One of the command line parameters to + <citerefentry> + <refentrytitle>sendmail</refentrytitle> + <manvolnum>8</manvolnum> + </citerefentry>, <option>-bp</option>, will display the + current status of messages in the mail queue. Check this + on the command line by running + <command>sendmail -bp</command>.</para> + </example> + + <note> + <para>Notice how the + <literal>&man.<replaceable>command</replaceable>.<replaceable>section</replaceable>;</literal> + notation is easier to follow.</para> + </note> + </sect3> + + <sect3> + <title>Files, Directories, Extensions</title> + + <para>Whenever you wish to refer to the name of a file, a + directory, or a file extension, use + <sgmltag>filename</sgmltag>.</para> + + <example> + <title><sgmltag>filename</sgmltag></title> + + <para>Use:</para> + + <programlisting><![CDATA[<para>The SGML source for the Handbook in English can be + found in <filename class="directory">/usr/doc/en_US.ISO8859-1/books/handbook/</filename>. The first + file is called <filename>book.xml</filename> in that + directory. You should also see a <filename>Makefile</filename> + and a number of files with a <filename>.ent</filename> + extension.</para>]]></programlisting> + + <para>Appearance:</para> + + <para>The SGML source for the Handbook in English can be + found in <filename>/usr/doc/en/handbook/</filename>. The + first file is called <filename>handbook.xml</filename> in + that directory. You should also see a + <filename>Makefile</filename> and a number of files with a + <filename>.ent</filename> extension.</para> + </example> + </sect3> + + <sect3> + <title>The Name of Ports</title> + + <note> + <title>&os; Extension</title> + + <para>These elements are part of the FreeBSD extension to + DocBook, and do not exist in the original DocBook + DTD.</para> + </note> + + <para>You might need to include the name of a program from the + FreeBSD Ports Collection in the documentation. Use the + <sgmltag>filename</sgmltag> tag with the + <literal>role</literal> attribute set to + <literal>package</literal> to identify these. Since ports + can be installed in any number of locations, only include + the category and the port name; do not include + <filename>/usr/ports</filename>.</para> + + <example> + <title><sgmltag>filename</sgmltag> Tag with + <literal>package</literal> Role</title> + + <para>Use:</para> + + <programlisting><![CDATA[<para>Install the <filename role="package">net/ethereal</filename> port to view network traffic.</para>]]></programlisting> + + <para>Appearance:</para> + + <para>Install the <filename + role="package">net/ethereal</filename> port to view + network traffic.</para> + </example> + </sect3> + + <sect3> + <title>Devices</title> + + <note> + <title>&os; Extension</title> + + <para>These elements are part of the FreeBSD extension to + DocBook, and do not exist in the original DocBook + DTD.</para> + </note> + + <para>When referring to devices you have two choices. You can + either refer to the device as it appears in + <filename>/dev</filename>, or you can use the name of the + device as it appears in the kernel. For this latter course, + use <sgmltag>devicename</sgmltag>.</para> + + <para>Sometimes you will not have a choice. Some devices, + such as networking cards, do not have entries in + <filename>/dev</filename>, or the entries are markedly + different from those entries.</para> + + <example> + <title><sgmltag>devicename</sgmltag></title> + + <para>Use:</para> + + <programlisting><![CDATA[<para><devicename>sio</devicename> is used for serial + communication in FreeBSD. <devicename>sio</devicename> manifests + through a number of entries in <filename>/dev</filename>, including + <filename>/dev/ttyd0</filename> and <filename>/dev/cuaa0</filename>.</para> + +<para>By contrast, the networking devices, such as + <devicename>ed0</devicename> do not appear in <filename>/dev</filename>.</para> + +<para>In MS-DOS, the first floppy drive is referred to as + <devicename>a:</devicename>. In FreeBSD it is + <filename>/dev/fd0</filename>.</para>]]></programlisting> + + <para>Appearance:</para> + + <para><devicename>sio</devicename> is used for serial + communication in FreeBSD. <devicename>sio</devicename> + manifests through a number of entries in + <filename>/dev</filename>, including + <filename>/dev/ttyd0</filename> and + <filename>/dev/cuaa0</filename>.</para> + + <para>By contrast, the networking devices, such as + <devicename>ed0</devicename> do not appear in + <filename>/dev</filename>.</para> + + <para>In MS-DOS, the first floppy drive is referred to as + <devicename>a:</devicename>. In FreeBSD it is + <filename>/dev/fd0</filename>.</para> + </example> + </sect3> + + <sect3> + <title>Hosts, Domains, IP Addresses, and So Forth</title> + + <note> + <title>&os; Extension</title> + + <para>These elements are part of the FreeBSD extension to + DocBook, and do not exist in the original DocBook + DTD.</para> + </note> + + <para>You can markup identification information for networked + computers (hosts) in several ways, depending on the nature + of the information. All of them use + <sgmltag>hostid</sgmltag> as the element, with the + <literal>role</literal> attribute selecting the type of the + marked up information.</para> + + <variablelist> + <varlistentry> + <term>No <literal>role</literal> attribute, or + <literal>role="hostname"</literal></term> + + <listitem> + <para>With no <literal>role</literal> attribute (i.e., + <sgmltag>hostid</sgmltag>...<sgmltag>/hostid</sgmltag>) + the marked up information is the simple hostname, such + as <literal>freefall</literal> or + <literal>wcarchive</literal>. You can explicitly + specify this with + <literal>role="hostname"</literal>.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>role="domainname"</literal></term> + + <listitem> + <para>The text is a domain name, such as + <literal>FreeBSD.org</literal> or + <literal>ngo.org.uk</literal>. There is no hostname + component.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>role="fqdn"</literal></term> + + <listitem> + <para>The text is a Fully Qualified Domain Name, with + both hostname and domain name parts.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>role="ipaddr"</literal></term> + + <listitem> + <para>The text is an IP address, probably expressed as a + dotted quad.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>role="ip6addr"</literal></term> + + <listitem> + <para>The text is an IPv6 address.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>role="netmask"</literal></term> + + <listitem> + <para>The text is a network mask, which might be + expressed as a dotted quad, a hexadecimal string, or + as a <literal>/</literal> followed by a number.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>role="mac"</literal></term> + + <listitem> + <para>The text is an Ethernet MAC address, expressed as + a series of 2 digit hexadecimal numbers separated by + colons.</para> + </listitem> + </varlistentry> + </variablelist> + + <example> + <title><sgmltag>hostid</sgmltag> and Roles</title> + + <para>Use:</para> + + <programlisting><![CDATA[<para>The local machine can always be referred to by the + name <hostid>localhost</hostid>, which will have the IP address + <hostid role="ipaddr">127.0.0.1</hostid>.</para> + +<para>The <hostid role="domainname">FreeBSD.org</hostid> domain + contains a number of different hosts, including + <hostid role="fqdn">freefall.FreeBSD.org</hostid> and + <hostid role="fqdn">pointyhat.FreeBSD.org</hostid>.</para> + +<para>When adding an IP alias to an interface (using + <command>ifconfig</command>) <emphasis>always</emphasis> use a + netmask of <hostid role="netmask">255.255.255.255</hostid> + (which can also be expressed as <hostid + role="netmask">0xffffffff</hostid>).</para> + +<para>The MAC address uniquely identifies every network card + in existence. A typical MAC address looks like <hostid + role="mac">08:00:20:87:ef:d0</hostid>.</para>]]></programlisting> + + <para>Appearance:</para> + + <para>The local machine can always be referred to by the + name <hostid>localhost</hostid>, which will have the IP + address <hostid role="ipaddr">127.0.0.1</hostid>.</para> + + <para>The <hostid role="domainname">FreeBSD.org</hostid> + domain contains a number of different hosts, including + <hostid role="fqdn">freefall.FreeBSD.org</hostid> and + <hostid role="fqdn">bento.FreeBSD.org</hostid>.</para> + + <para>When adding an IP alias to an interface (using + <command>ifconfig</command>) <emphasis>always</emphasis> + use a netmask of + <hostid role="netmask">255.255.255.255</hostid> + (which can also be expressed as <hostid + role="netmask">0xffffffff</hostid>).</para> + + <para>The MAC address uniquely identifies every network card + in existence. A typical MAC address looks like <hostid + role="mac">08:00:20:87:ef:d0</hostid>.</para> + </example> + </sect3> + + <sect3> + <title>Usernames</title> + + <note> + <title>&os; Extension</title> + + <para>These elements are part of the FreeBSD extension to + DocBook, and do not exist in the original DocBook + DTD.</para> + </note> + + <para>When you need to refer to a specific username, such as + <literal>root</literal> or <literal>bin</literal>, use + <sgmltag>username</sgmltag>.</para> + + <example> + <title><sgmltag>username</sgmltag></title> + + <para>Use:</para> + + <programlisting><![CDATA[<para>To carry out most system administration functions you + will need to be <username>root</username>.</para>]]></programlisting> + + <para>Appearance:</para> + + <para>To carry out most system administration functions you + will need to be <username>root</username>.</para> + </example> + </sect3> + + <sect3> + <title>Describing <filename>Makefile</filename>s</title> + + <note> + <title>&os; Extension</title> + + <para>These elements are part of the FreeBSD extension to + DocBook, and do not exist in the original DocBook + DTD.</para> + </note> + + <para>Two elements exist to describe parts of + <filename>Makefile</filename>s, + <sgmltag>maketarget</sgmltag> and + <sgmltag>makevar</sgmltag>.</para> + + <para><sgmltag>maketarget</sgmltag> identifies a build target + exported by a <filename>Makefile</filename> that can be + given as a parameter to <command>make</command>. + <sgmltag>makevar</sgmltag> identifies a variable that can be + set (in the environment, on the <command>make</command> + command line, or within the <filename>Makefile</filename>) + to influence the process.</para> + + <example> + <title><sgmltag>maketarget</sgmltag> and + <sgmltag>makevar</sgmltag></title> + + <para>Use:</para> + + <programlisting><![CDATA[<para>Two common targets in a <filename>Makefile</filename> + are <maketarget>all</maketarget> and <maketarget>clean</maketarget>.</para> + +<para>Typically, invoking <maketarget>all</maketarget> will rebuild the + application, and invoking <maketarget>clean</maketarget> will remove + the temporary files (<filename>.o</filename> for example) created by + the build process.</para> + +<para><maketarget>clean</maketarget> may be controlled by a number of + variables, including <makevar>CLOBBER</makevar> and + <makevar>RECURSE</makevar>.</para>]]></programlisting> + + <para>Appearance:</para> + + <para>Two common targets in a <filename>Makefile</filename> + are <maketarget>all</maketarget> and + <maketarget>clean</maketarget>.</para> + + <para>Typically, invoking <maketarget>all</maketarget> will + rebuild the application, and invoking + <maketarget>clean</maketarget> will remove the temporary + files (<filename>.o</filename> for example) created by the + build process.</para> + + <para><maketarget>clean</maketarget> may be controlled by a + number of variables, including <makevar>CLOBBER</makevar> + and <makevar>RECURSE</makevar>.</para> + </example> + </sect3> + + <sect3> + <title>Literal Text</title> + + <para>You will often need to include <quote>literal</quote> + text in the documentation. This is text that is excerpted + from another file, or which should be copied from the + documentation into another file verbatim.</para> + + <para>Some of the time, <sgmltag>programlisting</sgmltag> will + be sufficient to denote this text. + <sgmltag>programlisting</sgmltag> is not always appropriate, + particularly when you want to include a portion of a file + <quote>in-line</quote> with the rest of the + paragraph.</para> + + <para>On these occasions, use + <sgmltag>literal</sgmltag>.</para> + + <example> + <title><sgmltag>literal</sgmltag></title> + + <para>Use:</para> + + <programlisting><![CDATA[<para>The <literal>maxusers 10</literal> line in the kernel + configuration file determines the size of many system tables, and is + a rough guide to how many simultaneous logins the system will + support.</para>]]></programlisting> + + <para>Appearance:</para> + + <para>The <literal>maxusers 10</literal> line in the kernel + configuration file determines the size of many system + tables, and is a rough guide to how many simultaneous + logins the system will support.</para> + </example> + </sect3> + + <sect3> + <title>Showing Items That the User <emphasis>Must</emphasis> + Fill In</title> + + <para>There will often be times when you want to show the user + what to do, or refer to a file, or command line, or similar, + where the user cannot simply copy the examples that you + provide, but must instead include some information + themselves.</para> + + <para><sgmltag>replaceable</sgmltag> is designed for this + eventuality. Use it <emphasis>inside</emphasis> other + elements to indicate parts of that element's content that + the user must replace.</para> + + <example> + <title><sgmltag>replaceable</sgmltag></title> + + <para>Use:</para> + + <programlisting><![CDATA[<screen>&prompt.user; <userinput>man <replaceable>command</replaceable></userinput></screen>]]></programlisting> + + <para>Appearance:</para> + + <informalexample> + <screen>&prompt.user; <userinput>man <replaceable>command</replaceable></userinput></screen> + </informalexample> + + <para><sgmltag>replaceable</sgmltag> can be used in many + different elements, including <sgmltag>literal</sgmltag>. + This example also shows that + <sgmltag>replaceable</sgmltag> should only be wrapped + around the content that the user <emphasis>is</emphasis> + meant to provide. The other content should be left + alone.</para> + + <para>Use:</para> + + <programlisting><![CDATA[<para>The <literal>maxusers <replaceable>n</replaceable></literal> + line in the kernel configuration file determines the size of many system + tables, and is a rough guide to how many simultaneous logins the system will + support.</para> + +<para>For a desktop workstation, <literal>32</literal> is a good value + for <replaceable>n</replaceable>.</para>]]></programlisting> + + <para>Appearance:</para> + + <para>The + <literal>maxusers <replaceable>n</replaceable></literal> + line in the kernel configuration file determines the size + of many system tables, and is a rough guide to how many + simultaneous logins the system will support.</para> + + <para>For a desktop workstation, <literal>32</literal> is a + good value for <replaceable>n</replaceable>.</para> + </example> + </sect3> + + <sect3> + <title>Quoting System Errors</title> + + <para>You might want to show errors generated by FreeBSD. + Mark these with <sgmltag>errorname</sgmltag>. This + indicates the exact error that appears.</para> + + <example> + <title><sgmltag>errorname</sgmltag></title> + + <para>Use:</para> + + <programlisting><![CDATA[ +<screen><errorname>Panic: cannot mount root</errorname></screen> ]]> +</programlisting> + + + <para>Appearance:</para> + + <informalexample> + <screen><errorname>Panic: cannot mount root</errorname></screen> + </informalexample> + </example> + </sect3> + </sect2> + + <sect2> + <title>Images</title> + + <important> + <para>Image support in the documentation is currently + extremely experimental. The mechanisms described here are + unlikely to change, but that is not guaranteed.</para> + + <para>You will also need to install the + <filename role="package">graphics/ImageMagick</filename> + port, which is used to convert between the different image + formats. This is a big port, and most of it is not + required. However, while we are working on the + <filename>Makefile</filename>s and other infrastructure it + makes things easier. This port is <emphasis>not</emphasis> + in the <filename role="package">textproc/docproj</filename> + meta port, you must install it by hand.</para> + + <para>The best example of what follows in practice is the + <filename>doc/en_US.ISO8859-1/articles/vm-design/</filename> + document. If you are unsure of the description that + follows, take a look at the files in that directory to see + how everything hangs together. Experiment with creating + different formatted versions of the document to see how the + image markup appears in the formatted output.</para> + </important> + + <sect3> + <title>Image Formats</title> + + <para>We currently support two formats for images. The format + you should use will depend on the nature of your + image.</para> + + <para>For images that are primarily vector based, such as + network diagrams, time lines, and similar, use Encapsulated + Postscript, and make sure that your images have the + <filename>.eps</filename> extension.</para> + + <para>For bitmaps, such as screen captures, use the Portable + Network Graphic format, and make sure that your images have + the <filename>.png</filename> extension.</para> + + <para>These are the <emphasis>only</emphasis> formats in which + images should be committed to the Subversion + repository.</para> + + <para>Use the right format for the right image. It is to be + expected that your documentation will have a mix of EPS and + PNG images. The <filename>Makefile</filename>s ensure that + the correct format image is chosen depending on the output + format that you use for your documentation. <emphasis>Do + not commit the same image to the repository in two different + formats</emphasis>.</para> + + <important> + <para>It is anticipated that the Documentation Project will + switch to using the Scalable Vector Graphic (SVG) format + for vector images. However, the current state of SVG + capable editing tools makes this impractical.</para> + </important> + </sect3> + + <sect3> + <title>Markup</title> + + <para>The markup for an image is relatively simple. First, + markup a <sgmltag>mediaobject</sgmltag>. The + <sgmltag>mediaobject</sgmltag> can contain other, more + specific objects. We are concerned with two, the + <sgmltag>imageobject</sgmltag> and the + <sgmltag>textobject</sgmltag>.</para> + + <para>You should include one <sgmltag>imageobject</sgmltag>, + and two <sgmltag>textobject</sgmltag> elements. The + <sgmltag>imageobject</sgmltag> will point to the name of the + image file that will be used (without the extension). The + <sgmltag>textobject</sgmltag> elements contain information + that will be presented to the user as well as, or instead + of, the image.</para> + + <para>There are two circumstances where this can + happen.</para> + + <itemizedlist> + <listitem> + <para>When the reader is viewing the documentation in + HTML. In this case, each image will need to have + associated alternate text to show the user, typically + whilst the image is loading, or if they hover the mouse + pointer over the image.</para> + </listitem> + + <listitem> + <para>When the reader is viewing the documentation in + plain text. In this case, each image should have an + ASCII art equivalent to show the user.</para> + </listitem> + </itemizedlist> + + <para>An example will probably make things easier to + understand. Suppose you have an image, called + <filename>fig1.png</filename>, that you want to include in the + document. This image is of a rectangle with an A inside it. + The markup for this would be as follows.</para> + + <programlisting><mediaobject> + <imageobject> + <imagedata fileref="fig1"> <co id="co-image-ext"/> + </imageobject> + + <textobject> + <literallayout class="monospaced">+---------------+ <co id="co-image-literal"/> +| A | ++---------------+</literallayout> + </textobject> + + <textobject> + <phrase>A picture</phrase> <co id="co-image-phrase"/> + </textobject> +</mediaobject></programlisting> + + <calloutlist> + <callout arearefs="co-image-ext"> + <para>Include an <sgmltag>imagedata</sgmltag> element + inside the <sgmltag>imageobject</sgmltag> element. The + <literal>fileref</literal> attribute should contain the + filename of the image to include, without the extension. + The stylesheets will work out which extension should be + added to the filename automatically.</para> + </callout> + + <callout arearefs="co-image-literal"> + + <para>The first <sgmltag>textobject</sgmltag> should + contain a <sgmltag>literallayout</sgmltag> element, + where the <literal>class</literal> attribute is set to + <literal>monospaced</literal>. This is your opportunity + to demonstrate your ASCII art skills. This content will + be used if the document is converted to plain + text.</para> + + <para>Notice how the first and last lines of the content + of the <sgmltag>literallayout</sgmltag> element butt up + next to the element's tags. This ensures no extraneous + white space is included.</para> + </callout> + + <callout arearefs="co-image-phrase"> + <para>The second <sgmltag>textobject</sgmltag> should + contain a single <sgmltag>phrase</sgmltag> element. The + contents of this will become the <literal>alt</literal> + attribute for the image when this document is converted + to HTML.</para> + </callout> + </calloutlist> + </sect3> + + <sect3> + <title><filename>Makefile</filename> Entries</title> + + <para>Your images must be listed in the + <filename>Makefile</filename> in the + <makevar>IMAGES</makevar> variable. This variable should + contain the name of all your <emphasis>source</emphasis> + images. For example, if you have created three figures, + <filename>fig1.eps</filename>, + <filename>fig2.png</filename>, + <filename>fig3.png</filename>, then your + <filename>Makefile</filename> should have lines like this in + it.</para> + + <programlisting>… +IMAGES= fig1.eps fig2.png fig3.png +…</programlisting> + + <para>or</para> + + <programlisting>… +IMAGES= fig1.eps +IMAGES+= fig2.png +IMAGES+= fig3.png +…</programlisting> + + <para>Again, the <filename>Makefile</filename> will work out + the complete list of images it needs to build your source + document, you only need to list the image files + <emphasis>you</emphasis> provided.</para> + </sect3> + + <sect3> + <title>Images and Chapters in Subdirectories</title> + + <para>You must be careful when you separate your documentation + into smaller files (see + <xref linkend="xml-primer-include-using-gen-entities"/>) in + different directories.</para> + + <para>Suppose you have a book with three chapters, and the + chapters are stored in their own directories, called + <filename>chapter1/chapter.xml</filename>, + <filename>chapter2/chapter.xml</filename>, and + <filename>chapter3/chapter.xml</filename>. If each chapter + has images associated with it, it is suggested to place + those images in each chapter's subdirectory + (<filename>chapter1/</filename>, + <filename>chapter2/</filename>, and + <filename>chapter3/</filename>).</para> + + <para>However, if you do this you must include the directory + names in the <makevar>IMAGES</makevar> variable in the + <filename>Makefile</filename>, <emphasis>and</emphasis> you + must include the directory name in the + <sgmltag>imagedata</sgmltag> element in your + document.</para> + + <para>For example, if you have + <filename>chapter1/fig1.png</filename>, then + <filename>chapter1/chapter.xml</filename> should + contain:</para> + + <programlisting><mediaobject> + <imageobject> + <imagedata fileref="chapter1/fig1"> <co id="co-image-dir"/> + </imageobject> + + … + +</mediaobject></programlisting> + + <calloutlist> + <callout arearefs="co-image-dir"> + <para>The directory name must be included in the + <literal>fileref</literal> attribute.</para> + </callout> + </calloutlist> + + <para>The <filename>Makefile</filename> must contain:</para> + + <programlisting>… +IMAGES= chapter1/fig1.png +…</programlisting> + + <para>Then everything should just work.</para> + </sect3> + </sect2> + + <sect2> + <title>Links</title> + + <note> + <para>Links are also in-line elements.</para> + </note> + + <sect3> + <title>Linking to Other Parts of the Same Document</title> + + <para>Linking within the same document requires you to specify + where you are linking from (i.e., the text the user will + click, or otherwise indicate, as the source of the link) and + where you are linking to (the link's destination).</para> + + <para>Each element within DocBook has an attribute called + <literal>id</literal>. You can place text in this attribute + to uniquely name the element it is attached to.</para> + + <para>This value will be used when you specify the link + source.</para> + + <para>Normally, you will only be linking to chapters or + sections, so you would add the <literal>id</literal> + attribute to these elements.</para> + + <example> + <title>Attribute <literal>id</literal> on Chapters and + Sections</title> + + <programlisting><![CDATA[<chapter id="chapter1"> + <title>Introduction</title> + + <para>This is the introduction. It contains a subsection, + which is identified as well.</para> + + <sect1 id="chapter1-sect1"> + <title>Sub-sect 1</title> + + <para>This is the subsection.</para> + </sect1> +</chapter>]]></programlisting> + </example> + + <para>Obviously, you should use more descriptive values. The + values must be unique within the document (i.e., not just + the file, but the document the file might be included in as + well). Notice how the <literal>id</literal> for the + subsection is constructed by appending text to the + <literal>id</literal> of the chapter. This helps to ensure + that they are unique.</para> + + <para>If you want to allow the user to jump into a specific + portion of the document (possibly in the middle of a + paragraph or an example), use <sgmltag>anchor</sgmltag>. + This element has no content, but takes an + <literal>id</literal> attribute.</para> + + <example> + <title><sgmltag>anchor</sgmltag></title> + + <programlisting><![CDATA[<para>This paragraph has an embedded + <anchor id="para1">link target in it. It will not show up in + the document.</para>]]></programlisting> + </example> + + <para>When you want to provide the user with a link they can + activate (probably by clicking) to go to a section of the + document that has an <literal>id</literal> attribute, you + can use either <sgmltag>xref</sgmltag> or + <sgmltag>link</sgmltag>.</para> + + <para>Both of these elements have a <literal>linkend</literal> + attribute. The value of this attribute should be the value + that you have used in a <literal>id</literal> attribute (it + does not matter if that value has not yet occurred in your + document; this will work for forward links as well as + backward links).</para> + + <para>If you use <sgmltag>xref</sgmltag> then you have no + control over the text of the link. It will be generated for + you.</para> + + <example> + <title>Using <sgmltag>xref</sgmltag></title> + + <para>Assume that this fragment appears somewhere in a + document that includes the <literal>id</literal> + example:</para> + + <programlisting><![CDATA[<para>More information can be found + in <xref linkend="chapter1"/>.</para> + +<para>More specific information can be found + in <xref linkend="chapter1-sect1"/>.</para>]]></programlisting> + + <para>The text of the link will be generated automatically, + and will look like (<emphasis>emphasized</emphasis> text + indicates the text that will be the link):</para> + + <blockquote> + <para>More information can be found in <emphasis>Chapter + One</emphasis>.</para> + + <para>More specific information can be found in + <emphasis>the section called Sub-Sect + 1</emphasis>.</para> + </blockquote> + </example> + + <para>Notice how the text from the link is derived from the + section title or the chapter number.</para> + + <note> + <para>This means that you <emphasis>cannot</emphasis> use + <sgmltag>xref</sgmltag> to link to an + <literal>id</literal> attribute on an + <sgmltag>anchor</sgmltag> element. The + <sgmltag>anchor</sgmltag> has no content, so the + <sgmltag>xref</sgmltag> cannot generate the text for the + link.</para> + </note> + + <para>If you want to control the text of the link then use + <sgmltag>link</sgmltag>. This element wraps content, and + the content will be used for the link.</para> + + <example> + <title>Using <sgmltag>link</sgmltag></title> + + <para>Assume that this fragment appears somewhere in a + document that includes the <literal>id</literal> + example.</para> + + <programlisting><![CDATA[<para>More information can be found in + <link linkend="chapter1">the first chapter</link>.</para> + +<para>More specific information can be found in + <link linkend="chapter1-sect1">this</link> section.</para>]]></programlisting> + + <para>This will generate the following + (<emphasis>emphasized</emphasis> text indicates the text + that will be the link):</para> + + <blockquote> + <para>More information can be found in <emphasis>the first + chapter</emphasis>.</para> + + <para>More specific information can be found in + <emphasis>this</emphasis> section.</para> + </blockquote> + </example> + + <note> + <para>That last one is a bad example. Never use words like + <quote>this</quote> or <quote>here</quote> as the source + for the link. The reader will need to hunt around the + surrounding context to see where the link is actually + taking them.</para> + </note> + + <note> + <para>You <emphasis>can</emphasis> use + <sgmltag>link</sgmltag> to include a link to an + <literal>id</literal> on an <sgmltag>anchor</sgmltag> + element, since the <sgmltag>link</sgmltag> content defines + the text that will be used for the link.</para> + </note> + </sect3> + + <sect3> + <title>Linking to Documents on the WWW</title> + + <para>Linking to external documents is much simpler, as long + as you know the URL of the document you want to link to. + Use <sgmltag>ulink</sgmltag>. The <literal>url</literal> + attribute is the URL of the page that the link points to, + and the content of the element is the text that will be + displayed for the user to activate.</para> + + <example> + <title><sgmltag>ulink</sgmltag></title> + + <para>Use:</para> + + <programlisting><![CDATA[<para>Of course, you could stop reading this document and + go to the <ulink url="&url.base;/index.html">FreeBSD + home page</ulink> instead.</para>]]></programlisting> + + <para>Appearance:</para> + + <para>Of course, you could stop reading this document and go + to the <ulink url="&url.base;/index.html">FreeBSD home + page</ulink> instead.</para> + </example> + </sect3> + </sect2> + </sect1> +</chapter> diff --git a/en_US.ISO8859-1/books/fdp-primer/sgml-primer/chapter.xml b/en_US.ISO8859-1/books/fdp-primer/sgml-primer/chapter.xml new file mode 100644 index 0000000000..9072cb4999 --- /dev/null +++ b/en_US.ISO8859-1/books/fdp-primer/sgml-primer/chapter.xml @@ -0,0 +1,1534 @@ +<?xml version="1.0" encoding="iso-8859-1"?> +<!-- Copyright (c) 1998, 1999 Nik Clayton, All rights reserved. + + Redistribution and use in source (SGML DocBook) and 'compiled' forms + (SGML, HTML, PDF, PostScript, RTF and so forth) with or without + modification, are permitted provided that the following conditions + are met: + + 1. Redistributions of source code (SGML DocBook) must retain the above + copyright notice, this list of conditions and the following + disclaimer as the first lines of this file unmodified. + + 2. Redistributions in compiled form (transformed to other DTDs, + converted to PDF, PostScript, RTF and other formats) must reproduce + the above copyright notice, this list of conditions and the + following disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS DOCUMENTATION IS PROVIDED BY NIK CLAYTON "AS IS" AND ANY EXPRESS OR + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL NIK CLAYTON BE LIABLE FOR ANY DIRECT, + INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + ANY WAY OUT OF THE USE OF THIS DOCUMENTATION, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + $FreeBSD$ +--> + +<chapter id="xml-primer"> + <title>XML Primer</title> + + <para>The majority of FDP documentation is written in applications + of XML. This chapter explains exactly what that means, how to + read and understand the source to the documentation, and the sort + of XML tricks you will see used in the documentation.</para> + + <para>Portions of this section were inspired by Mark Galassi's + <ulink url="http://www.galassi.org/mark/mydocs/docbook-intro/docbook-intro.html">Get + Going With DocBook</ulink>.</para> + + <sect1 id="xml-primer-overview"> + <title>Overview</title> + + <para>Way back when, electronic text was simple to deal with. + Admittedly, you had to know which character set your document + was written in (ASCII, EBCDIC, or one of a number of others) but + that was about it. Text was text, and what you saw really was + what you got. No frills, no formatting, no intelligence.</para> + + <para>Inevitably, this was not enough. Once you have text in a + machine-usable format, you expect machines to be able to use it + and manipulate it intelligently. You would like to indicate + that certain phrases should be emphasized, or added to a + glossary, or be hyperlinks. You might want filenames to be + shown in a <quote>typewriter</quote> style font for viewing on + screen, but as <quote>italics</quote> when printed, or any of a + myriad of other options for presentation.</para> + + <para>It was once hoped that Artificial Intelligence (AI) would + make this easy. Your computer would read in the document and + automatically identify key phrases, filenames, text that the + reader should type in, examples, and more. Unfortunately, real + life has not happened quite like that, and our computers require + some assistance before they can meaningfully process our + text.</para> + + <para>More precisely, they need help identifying what is what. + Let's look at this text:</para> + + <blockquote> + <para>To remove <filename>/tmp/foo</filename> use + &man.rm.1;.</para> + + <screen>&prompt.user; <userinput>rm /tmp/foo</userinput></screen> + </blockquote> + + <para>It is easy to see which parts are filenames, which are + commands to be typed in, which parts are references to manual + pages, and so on. But the computer processing the document + cannot. For this we need markup.</para> + + <para><quote>Markup</quote> is commonly used to describe + <quote>adding value</quote> or <quote>increasing cost</quote>. + The term takes on both these meanings when applied to text. + Markup is additional text included in the document, + distinguished from the document's content in some way, so that + programs that process the document can read the markup and use + it when making decisions about the document. Editors can hide + the markup from the user, so the user is not distracted by + it.</para> + + <para>The extra information stored in the markup <emphasis>adds + value</emphasis> to the document. Adding the markup to the + document must typically be done by a person—after all, if + computers could recognize the text sufficiently well to add the + markup then there would be no need to add it in the first place. + This <emphasis>increases the cost</emphasis> (i.e., the effort + required) to create the document.</para> + + <para>The previous example is actually represented in this + document like this:</para> + + <programlisting><![CDATA[ +<para>To remove <filename>/tmp/foo</filename> use &man.rm.1;.</para> + +<screen>&prompt.user; <userinput>rm /tmp/foo</userinput></screen>]]></programlisting> + + <para>As you can see, the markup is clearly separate from the + content.</para> + + <para>Obviously, if you are going to use markup you need to define + what your markup means, and how it should be interpreted. You + will need a markup language that you can follow when marking up + your documents.</para> + + <para>Of course, one markup language might not be enough. A + markup language for technical documentation has very different + requirements than a markup language that was to be used for + cookery recipes. This, in turn, would be very different from a + markup language used to describe poetry. What you really need + is a first language that you use to write these other markup + languages. A <emphasis>meta markup language</emphasis>.</para> + + <para>This is exactly what the eXtensible Markup + Language (XML) is. Many markup languages have been written in + XML, including the two most used by the FDP, XHTML and + DocBook.</para> + + <para>Each language definition is more properly called a grammar, + vocabulary, schema or Document Type Definition (DTD). There + are various languages to specify an XML grammar, for example, + DTD (yes, it also means the specification language itself), + XML Schema (XSD) or RELANG NG. The schema specifies the name + of the elements that can be used, what order they appear in (and + whether some markup can be used inside other markup) and related + information.</para> + + <para id="xml-primer-validating">A schema is a + <emphasis>complete</emphasis> specification of all the elements + that are allowed to appear, the order in which they should + appear, which elements are mandatory, which are optional, and so + forth. This makes it possible to write an XML + <emphasis>parser</emphasis> which reads in both the schema and a + document which claims to conform to the schema. The parser can + then confirm whether or not all the elements required by the vocabulary + are in the document in the right order, and whether there are + any errors in the markup. This is normally referred to as + <quote>validating the document</quote>.</para> + + <note> + <para>This processing simply confirms that the choice of + elements, their ordering, and so on, conforms to that listed + in the grammar. It does <emphasis>not</emphasis> check that you + have used <emphasis>appropriate</emphasis> markup for the + content. If you tried to mark up all the filenames in your + document as function names, the parser would not flag this as + an error (assuming, of course, that your schema defines elements + for filenames and functions, and that they are allowed to + appear in the same place).</para> + </note> + + <para>It is likely that most of your contributions to the + Documentation Project will consist of content marked up in + either XHTML or DocBook, rather than alterations to the schemas. + For this reason this book will not touch on how to write a + vocabulary.</para> + </sect1> + + <sect1 id="xml-primer-elements"> + <title>Elements, Tags, and Attributes</title> + + <para>All the vocabularies written in XML share certain characteristics. + This is hardly surprising, as the philosophy behind XML will + inevitably show through. One of the most obvious manifestations + of this philosophy is that of <emphasis>content</emphasis> and + <emphasis>elements</emphasis>.</para> + + <para>Your documentation (whether it is a single web page, or a + lengthy book) is considered to consist of content. This content + is then divided (and further subdivided) into elements. The + purpose of adding markup is to name and identify the boundaries + of these elements for further processing.</para> + + <para>For example, consider a typical book. At the very top + level, the book is itself an element. This <quote>book</quote> + element obviously contains chapters, which can be considered to + be elements in their own right. Each chapter will contain more + elements, such as paragraphs, quotations, and footnotes. Each + paragraph might contain further elements, identifying content + that was direct speech, or the name of a character in the + story.</para> + + <para>You might like to think of this as <quote>chunking</quote> + content. At the very top level you have one chunk, the book. + Look a little deeper, and you have more chunks, the individual + chapters. These are chunked further into paragraphs, footnotes, + character names, and so on.</para> + + <para>Notice how you can make this differentiation between + different elements of the content without resorting to any XML + terms. It really is surprisingly straightforward. You could do + this with a highlighter pen and a printout of the book, using + different colors to indicate different chunks of content.</para> + + <para>Of course, we do not have an electronic highlighter pen, so + we need some other way of indicating which element each piece of + content belongs to. In languages written in XML (XHTML, + DocBook, et al) this is done by means of + <emphasis>tags</emphasis>.</para> + + <para>A tag is used to identify where a particular element starts, + and where the element ends. <emphasis>The tag is not part of + the element itself</emphasis>. Because each grammar was normally + written to mark up specific types of information, each one will + recognize different elements, and will therefore have different + names for the tags.</para> + + <para>For an element called + <replaceable>element-name</replaceable> the start tag will + normally look like + <sgmltag><replaceable>element-name</replaceable></sgmltag>. The + corresponding closing tag for this element is + <sgmltag>/<replaceable>element-name</replaceable></sgmltag>.</para> + + <example> + <title>Using an Element (Start and End Tags)</title> + + <para>XHTML has an element for indicating that the content + enclosed by the element is a paragraph, called + <sgmltag>p</sgmltag>.</para> + + <programlisting><![CDATA[<p>This is a paragraph. It starts with the start tag for + the 'p' element, and it will end with the end tag for the 'p' + element.</p> + +<p>This is another paragraph. But this one is much shorter.</p>]]></programlisting> + </example> + + <para>Some elements have no + content. For example, in XHTML you can indicate that you want a + horizontal line to appear in the document.</para> + + <para>For such elements, that have no content at all, XML introduced + a shorthand form, which is ccompletely equivalent to the above + form:</para> + + <programlisting><![CDATA[<hr/>]]></programlisting> + + <example> + <title>Using an Element (Without Content)</title> + + <para>XHTML has an element for indicating a horizontal rule, + called <sgmltag>hr</sgmltag>. This element does not wrap + content, so it looks like this.</para> + + <programlisting><![CDATA[<p>One paragraph.</p> +<hr></hr> + +<p>This is another paragraph. A horizontal rule separates this + from the previous paragraph.</p>]]></programlisting> + + <para>For such elements, that have no content at all, XML introduced + a shorthand form, which is ccompletely equivalent to the above + form:</para> + + <programlisting><![CDATA[<p>One paragraph.</p> +<hr/> + +<p>This is another paragraph. A horizontal rule separates this + from the previous paragraph.</p>]]></programlisting> + </example> + + <para>If it is not obvious by now, elements can contain other + elements. In the book example earlier, the book element + contained all the chapter elements, which in turn contained all + the paragraph elements, and so on.</para> + + <example> + <title>Elements within Elements; <sgmltag>em</sgmltag></title> + + <programlisting><![CDATA[<p>This is a simple <em>paragraph</em> where some + of the <em>words</em> have been <em>emphasized</em>.</p>]]></programlisting> + </example> + + <para>The grammar will specify the rules detailing which elements can + contain other elements, and exactly what they can + contain.</para> + + <important> + <para>People often confuse the terms tags and elements, and use + the terms as if they were interchangeable. They are + not.</para> + + <para>An element is a conceptual part of your document. An + element has a defined start and end. The tags mark where the + element starts and end.</para> + + <para>When this document (or anyone else knowledgeable about + XML) refers to <quote>the <sgmltag>p</sgmltag> tag</quote> + they mean the literal text consisting of the three characters + <literal><</literal>, <literal>p</literal>, and + <literal>></literal>. But the phrase <quote>the + <sgmltag>p</sgmltag> element</quote> refers to the whole + element.</para> + + <para>This distinction <emphasis>is</emphasis> very subtle. But + keep it in mind.</para> + </important> + + <para>Elements can have attributes. An attribute has a name and a + value, and is used for adding extra information to the element. + This might be information that indicates how the content should + be rendered, or might be something that uniquely identifies that + occurrence of the element, or it might be something else.</para> + + <para>An element's attributes are written + <emphasis>inside</emphasis> the start tag for that element, and + take the form + <literal><replaceable>attribute-name</replaceable>="<replaceable>attribute-value</replaceable>"</literal>.</para> + + <para>In XHTML, the + <sgmltag>p</sgmltag> element has an attribute called + <sgmltag>align</sgmltag>, which suggests an alignment + (justification) for the paragraph to the program displaying the + XHTML.</para> + + <para>The <literal>align</literal> attribute can take one of four + defined values, <literal>left</literal>, + <literal>center</literal>, <literal>right</literal> and + <literal>justify</literal>. If the attribute is not specified + then the default is <literal>left</literal>.</para> + + <example> + <title>Using An Element with An Attribute</title> + + <programlisting><![CDATA[<p align="left">The inclusion of the align attribute + on this paragraph was superfluous, since the default is left.</p> + +<p align="center">This may appear in the center.</p>]]></programlisting> + </example> + + <para>Some attributes will only take specific values, such as + <literal>left</literal> or <literal>justify</literal>. Others + will allow you to enter anything you want.</para> + + <example> + <title>Single Quotes Around Attributes</title> + + <programlisting><![CDATA[<p align='right'>I am on the right!</p>]]></programlisting> + </example> + + <para>XML requires you to quote each attribute value with either + single or double quotes. It is more habitual to use double quotes + but you may use single quotes, as well. Using single quotes is + practical if you want to include double quotes in the attribute + value.</para> + + <para>The information on attributes, elements, and tags is stored + in XML catalogs. The various Documentation Project tools use + these catalog files to validate your work. The tools in + <filename role="package">textproc/docproj</filename> include a + variety of XML catalog files. The FreeBSD Documentation + Project includes its own set of catalog files. Your tools need + to know about both sorts of catalog files.</para> + + <sect2> + <title>For You to Do…</title> + + <para>In order to run the examples in this document you will + need to install some software on your system and ensure that + an environment variable is set correctly.</para> + + <procedure> + <step> + <para>Download and install + <filename role="package">textproc/docproj</filename> from + the FreeBSD ports system. This is a + <emphasis>meta-port</emphasis> that should download and + install all of the programs and supporting files that are + used by the Documentation Project.</para> + </step> + + <step> + <para>Add lines to your shell startup files to set + <envar>SGML_CATALOG_FILES</envar>. (If you are not working + on the English version of the documentation, you will want + to substitute the correct directory for your + language.)</para> + + <example id="xml-primer-envars"> + <title><filename>.profile</filename>, for &man.sh.1; and + &man.bash.1; Users</title> + + <programlisting>SGML_ROOT=/usr/local/share/xml +SGML_CATALOG_FILES=${SGML_ROOT}/jade/catalog +SGML_CATALOG_FILES=${SGML_ROOT}/docbook/4.1/catalog:$SGML_CATALOG_FILES +SGML_CATALOG_FILES=${SGML_ROOT}/html/catalog:$SGML_CATALOG_FILES +SGML_CATALOG_FILES=${SGML_ROOT}/iso8879/catalog:$SGML_CATALOG_FILES +SGML_CATALOG_FILES=/usr/doc/share/xml/catalog:$SGML_CATALOG_FILES +SGML_CATALOG_FILES=/usr/doc/en_US.ISO8859-1/share/xml/catalog:$SGML_CATALOG_FILES +export SGML_CATALOG_FILES</programlisting> + </example> + + <example> + <title><filename>.cshrc</filename>, for &man.csh.1; and + &man.tcsh.1; Users</title> + + <programlisting>setenv SGML_ROOT /usr/local/share/xml +setenv SGML_CATALOG_FILES ${SGML_ROOT}/jade/catalog +setenv SGML_CATALOG_FILES ${SGML_ROOT}/docbook/4.1/catalog:$SGML_CATALOG_FILES +setenv SGML_CATALOG_FILES ${SGML_ROOT}/html/catalog:$SGML_CATALOG_FILES +setenv SGML_CATALOG_FILES ${SGML_ROOT}/iso8879/catalog:$SGML_CATALOG_FILES +setenv SGML_CATALOG_FILES /usr/doc/share/xml/catalog:$SGML_CATALOG_FILES +setenv SGML_CATALOG_FILES /usr/doc/en_US.ISO8859-1/share/xml/catalog:$SGML_CATALOG_FILES</programlisting> + </example> + + <para>Then either log out, and log back in again, or run + those commands from the command line to set the variable + values.</para> + </step> + </procedure> + + <procedure> + <step> + <para>Create <filename>example.xml</filename>, and enter + the following text:</para> + + <programlisting><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> + +<html xmlns="http://www.w3.org/1999/xhtml"> + <head> + <title>An Example XHTML File</title> + </head> + + <body> + <p>This is a paragraph containing some text.</p> + + <p>This paragraph contains some more text.</p> + + <p align="right">This paragraph might be right-justified.</p> + </body> +</html>]]></programlisting> + </step> + + <step> + <para>Try to validate this file using an XML parser.</para> + + <para>Part of + <filename role="package">textproc/docproj</filename> is + the <command>xmllint</command> + <link linkend="xml-primer-validating">validating + parser</link>.</para> + + <para>Use <command>xmllint</command> in the following way to + check that your document is valid:</para> + + <screen>&prompt.user; <userinput>xmllint --valid --noout example.xml</userinput></screen> + + <para>As you will see, <command>xmllint</command> returns + without displaying any output. This means that your + document validated successfully.</para> + </step> + + <step> + <para>See what happens when required elements are omitted. + Try removing the <sgmltag>title</sgmltag> and + <sgmltag>/title</sgmltag> tags, and re-run the + validation.</para> + + <screen>&prompt.user; <userinput>xmllint --valid --noout example.xml</userinput> +example.xml:5: element head: validity error : Element head content does not follow the DTD, expecting ((script | style | meta | link | object | isindex)* , ((title , (script | style | meta | link | object | isindex)* , (base , (script | style | meta | link | object | isindex)*)?) | (base , (script | style | meta | link | object | isindex)* , title , (script | style | meta | link | object | isindex)*))), got ()</screen> + + <para>This line tells you that the validation error comes from + the <replaceable>fifth</replaceable> line of the + <replaceable>example.xml</replaceable> file and that the + content of the <sgmltag>head</sgmltag> is the part, which + does not follow the rules described by the XHTML grammar.</para> + + <para>Below this line <command>xmllint</command> will show you + the line where the error has been found and will also mark the + exact character position with a ^ sign.</para> + </step> + + <step> + <para>Put the <sgmltag>title</sgmltag> element back + in.</para> + </step> + </procedure> + </sect2> + </sect1> + + <sect1 id="xml-primer-doctype-declaration"> + <title>The DOCTYPE Declaration</title> + + <para>The beginning of each document that you write may specify + the name of the DTD that the document conforms to in case you use + the DTD specification language. Other specification languages, like + XML Schema and RELAX NG are not referred in the source document. + This DOCTYPE declaration serves the XML parsers so that they can + determine the DTD and ensure that the document does conform to it.</para> + + <para>A typical declaration for a document written to conform with + version 1.0 of the XHTML DTD looks like this:</para> + + <programlisting><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">]]></programlisting> + + <para>That line contains a number of different components.</para> + + <variablelist> + <varlistentry> + <term><literal><!</literal></term> + + <listitem> + <para>Is the <emphasis>indicator</emphasis> that indicates + that this is an XML declaration. This line is declaring + the document type.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>DOCTYPE</literal></term> + + <listitem> + <para>Shows that this is an XML declaration for the + document type.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>html</literal></term> + + <listitem> + <para>Names the first + <link linkend="xml-primer-elements">element</link> that + will appear in the document.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"</literal></term> + + <listitem> + <para>Lists the Formal Public Identifier (FPI) + <indexterm> + <primary>Formal Public Identifier</primary> + </indexterm> + for the DTD that this document conforms to. Your XML + parser will use this to find the correct DTD when + processing this document.</para> + + <para><literal>PUBLIC</literal> is not a part of the FPI, + but indicates to the XML processor how to find the DTD + referenced in the FPI. Other ways of telling the XML + parser how to find the DTD are shown <link + linkend="xml-primer-fpi-alternatives">later</link>.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"</literal></term> + + <listitem> + <para>A local filename or an URL to find the DTD.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>></literal></term> + + <listitem> + <para>Returns to the document.</para> + </listitem> + </varlistentry> + </variablelist> + + <sect2> + <title>Formal Public Identifiers (FPIs) + <indexterm significance="preferred"> + <primary>Formal Public Identifier</primary> + </indexterm></title> + + <note> + <para>You do not need to know this, but it is useful + background, and might help you debug problems when your XML + processor can not locate the DTD you are using.</para> + </note> + + <para>FPIs must follow a specific syntax. This syntax is as + follows:</para> + + <programlisting>"<replaceable>Owner</replaceable>//<replaceable>Keyword</replaceable> <replaceable>Description</replaceable>//<replaceable>Language</replaceable>"</programlisting> + + <variablelist> + <varlistentry> + <term><replaceable>Owner</replaceable></term> + + <listitem> + <para>This indicates the owner of the FPI.</para> + + <para>If this string starts with <quote>ISO</quote> then + this is an ISO owned FPI. For example, the FPI + <literal>"ISO 8879:1986//ENTITIES Greek + Symbols//EN"</literal> lists + <literal>ISO 8879:1986</literal> as being the owner for + the set of entities for Greek symbols. ISO 8879:1986 is + the ISO number for the SGML standard, the predecessor + (and a superset) of XML.</para> + + <para>Otherwise, this string will either look like + <literal>-//<replaceable>Owner</replaceable></literal> + or + <literal>+//<replaceable>Owner</replaceable></literal> + (notice the only difference is the leading + <literal>+</literal> or <literal>-</literal>).</para> + + <para>If the string starts with <literal>-</literal> then + the owner information is unregistered, with a + <literal>+</literal> it identifies it as being + registered.</para> + + <para>ISO 9070:1991 defines how registered names are + generated; it might be derived from the number of an ISO + publication, an ISBN code, or an organization code + assigned according to ISO 6523. In addition, a + registration authority could be created in order to + assign registered names. The ISO council delegated this + to the American National Standards Institute + (ANSI).</para> + + <para>Because the FreeBSD Project has not been registered + the owner string is <literal>-//FreeBSD</literal>. And + as you can see, the W3C are not a registered owner + either.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><replaceable>Keyword</replaceable></term> + + <listitem> + <para>There are several keywords that indicate the type of + information in the file. Some of the most common + keywords are <literal>DTD</literal>, + <literal>ELEMENT</literal>, <literal>ENTITIES</literal>, + and <literal>TEXT</literal>. <literal>DTD</literal> is + used only for DTD files, <literal>ELEMENT</literal> is + usually used for DTD fragments that contain only entity + or element declarations. <literal>TEXT</literal> is + used for XML content (text and tags).</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><replaceable>Description</replaceable></term> + + <listitem> + <para>Any description you want to supply for the contents + of this file. This may include version numbers or any + short text that is meaningful to you and unique for the + XML system.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><replaceable>Language</replaceable></term> + + <listitem> + <para>This is an ISO two-character code that identifies + the native language for the file. <literal>EN</literal> + is used for English.</para> + </listitem> + </varlistentry> + </variablelist> + + <sect3> + <title><filename>catalog</filename> Files</title> + + <para>If you use the syntax above and process this document + using an XML processor, the processor will need to have + some way of turning the FPI into the name of the file on + your computer that contains the DTD.</para> + + <para>In order to do this it can use a catalog file. A + catalog file (typically called <filename>catalog</filename>) + contains lines that map FPIs to filenames. For example, if + the catalog file contained the line:</para> + +<!-- XXX: mention XML catalog or maybe replace this totally and only cover XML catalog --> + + <programlisting>PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "1.0/transitional.dtd"</programlisting> + + <para>The XML processor would know to look up the DTD from + <filename>transitional.dtd</filename> in the + <filename>1.0</filename> subdirectory of whichever directory + held the <filename>catalog</filename> file that contained + that line.</para> + + <para>Look at the contents of + <filename>/usr/local/share/xml/dtd/xhtml/catalog.xml</filename>. + This is the catalog file for the XHTML DTDs that will have + been installed as part of the <filename + role="package">textproc/docproj</filename> port.</para> + </sect3> + + <sect3> + <title><envar>SGML_CATALOG_FILES</envar></title> + + <para>In order to locate a <filename>catalog</filename> file, + your XML processor will need to know where to look. Many + of them feature command line parameters for specifying the + path to one or more catalogs.</para> + + <para>In addition, you can set + <envar>SGML_CATALOG_FILES</envar> to point to the files. + This environment variable should consist of a + colon-separated list of catalog files (including their full + path).</para> + + <para>Typically, you will want to include the following + files:</para> + + <itemizedlist> + <listitem> + <para><filename>/usr/local/share/xml/docbook/4.1/catalog</filename></para> + </listitem> + + <listitem> + <para><filename>/usr/local/share/xml/html/catalog</filename></para> + </listitem> + + <listitem> + <para><filename>/usr/local/share/xml/iso8879/catalog</filename></para> + </listitem> + + <listitem> + <para><filename>/usr/local/share/xml/jade/catalog</filename></para> + </listitem> + </itemizedlist> + + <para>You should <link linkend="xml-primer-envars">already + have done this</link>.</para> + </sect3> + </sect2> + + <sect2 id="xml-primer-fpi-alternatives"> + <title>Alternatives to FPIs</title> + + <para>Instead of using an FPI to indicate the DTD that the + document conforms to (and therefore, which file on the system + contains the DTD) you can explicitly specify the name of the + file.</para> + + <para>The syntax for this is slightly different:</para> + + <programlisting><![CDATA[<!DOCTYPE html SYSTEM "/path/to/file.dtd">]]></programlisting> + + <para>The <literal>SYSTEM</literal> keyword indicates that the + XML processor should locate the DTD in a system specific + fashion. This typically (but not always) means the DTD will + be provided as a filename.</para> + + <para>Using FPIs is preferred for reasons of portability. You + do not want to have to ship a copy of the DTD around with your + document, and if you used the <literal>SYSTEM</literal> + identifier then everyone would need to keep their DTDs in the + same place.</para> + </sect2> + </sect1> + + <sect1 id="xml-primer-xml-escape"> + <title>Escaping Back to SGML</title> + + <para>As mentioned earlier, XML is only used when writing a DTD. + This is not strictly true. There is certain XML syntax that + you will want to be able to use within your documents. For + example, comments can be included in your document, and will be + ignored by the parser. Comments are entered using XML syntax. + Other uses for XML syntax in your document will be shown later + too.</para> + + <para>Obviously, you need some way of indicating to the XML + processor that the following content is not elements within the + document, but is XML that the parser should act upon.</para> + + <para>These sections are marked by + <literal><! ... ></literal> in your document. Everything + between these delimiters is XML syntax as you might find within + a DTD.</para> + + <para>As you may just have realized, the + <link linkend="xml-primer-doctype-declaration">DOCTYPE + declaration</link> is an example of XML syntax that you need + to include in your document…</para> + </sect1> + + <sect1 id="xml-primer-comments"> + <title>Comments</title> + + <para>Comments are an XML construction, and are normally only + valid inside a DTD. However, as + <xref linkend="xml-primer-xml-escape"/> shows, it is possible + to use XML syntax within your document.</para> + + <para>The delimiter for XML comments is the string + <quote><literal>--</literal></quote>. The first occurrence of + this string opens a comment, and the second closes it.</para> + + <example> + <title>XML Generic Comment</title> + + <programlisting><!-- test comment --></programlisting> + + <programlisting> +<!‐- This is inside the comment -‐> + +<!‐- This is another comment -‐> + +<!‐- This is one way + of doing multiline comments -‐> + +<!‐- This is another way of -‐ + ‐- doing multiline comments -‐></programlisting> + </example> + + <para>If you have used XHTML before you may have been shown + different rules for comments. In particular, you may think that + the string <literal><!--</literal> opens a comment, and it is + only closed by <literal>--></literal>.</para> + + <para>This is <emphasis>not</emphasis> the case. A lot of web + browsers have broken XHTML parsers, and will accept that as + valid. However, the XML parsers used by the Documentation + Project are much stricter, and will reject documents that make + that error.</para> + + <example> + <title>Erroneous XML Comments</title> + + <programlisting> +<!‐- This is in the comment -‐ + + THIS IS OUTSIDE THE COMMENT! + + ‐- back inside the comment -‐></programlisting> + + <para>The XML parser will treat this as though it were + actually:</para> + + <programlisting><!THIS IS OUTSIDE THE COMMENT></programlisting> + + <para>This is not valid XML, and may give confusing error + messages.</para> + + <programlisting>>!‐‐‐‐‐ This is a very bad idea ‐‐‐‐‐></programlisting> + + <para>As the example suggests, <emphasis>do not</emphasis> write + comments like that.</para> + + <programlisting>>!-‐===================================================-‐></programlisting> + + <para>That is a (slightly) better approach, but it still + potentially confusing to people new to XML.</para> + </example> + + <sect2> + <title>For You to Do…</title> + + <procedure> + <step> + <para>Add some comments to + <filename>example.xml</filename>, and check that the file + still validates using <command>xmllint</command>.</para> + </step> + + <step> + <para>Add some invalid comments to + <filename>example.xml</filename>, and see the error + messages that <command>xmllint</command> gives when it + encounters an invalid comment.</para> + </step> + </procedure> + </sect2> + </sect1> + + <sect1 id="xml-primer-entities"> + <title>Entities</title> + + <para>Entities are a mechanism for assigning names to chunks of + content. As an XML parser processes your document, any + entities it finds are replaced by the content of the + entity.</para> + + <para>This is a good way to have re-usable, easily changeable + chunks of content in your XML documents. It is also the only + way to include one marked up file inside another using + XML.</para> + + <para>There are two types of entities which can be used in two + different situations; <emphasis>general entities</emphasis> and + <emphasis>parameter entities</emphasis>.</para> + + <sect2 id="xml-primer-general-entities"> + <title>General Entities</title> + + <para>You cannot use general entities in an XML context + (although you define them in one). They can only be used in + your document. Contrast this with <link + linkend="xml-primer-parameter-entities">parameter + entities</link>.</para> + + <para>Each general entity has a name. When you want to + reference a general entity (and therefore include whatever + text it represents in your document), you write + <literal>&<replaceable>entity-name</replaceable>;</literal>. + For example, suppose you had an entity called + <literal>current.version</literal> which expanded to the + current version number of your product. You could + write:</para> + + <programlisting><![CDATA[<para>The current version of our product is + ¤t.version;.</para>]]></programlisting> + + <para>When the version number changes you can simply change the + definition of the value of the general entity and reprocess + your document.</para> + + <para>You can also use general entities to enter characters that + you could not otherwise include in an XML document. For + example, <literal><</literal> and <literal>&</literal> + cannot normally appear in an XML document. When the XML + parser sees the <literal><</literal> symbol it assumes that + a tag (either a start tag or an end tag) is about to appear, + and when it sees the <literal>&</literal> symbol it + assumes the next text will be the name of an entity.</para> + + <para>Fortunately, you can use the two general entities + <literal>&lt;</literal> and <literal>&amp;</literal> + whenever you need to include one or other of these.</para> + + <para>A general entity can only be defined within an XML + context. Typically, this is done immediately after the + DOCTYPE declaration.</para> + + <example> + <title>Defining General Entities</title> + + <programlisting><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" [ +<!ENTITY current.version "3.0-RELEASE"> +<!ENTITY last.version "2.2.7-RELEASE"> +]>]]></programlisting> + + <para>Notice how the DOCTYPE declaration has been extended by + adding a square bracket at the end of the first line. The + two entities are then defined over the next two lines, + before the square bracket is closed, and then the DOCTYPE + declaration is closed.</para> + + <para>The square brackets are necessary to indicate that we + are extending the DTD indicated by the DOCTYPE + declaration.</para> + </example> + </sect2> + + <sect2 id="xml-primer-parameter-entities"> + <title>Parameter Entities</title> + + <para>Like <link linkend="xml-primer-general-entities">general + entities</link>, parameter entities are used to assign names + to reusable chunks of text. However, whereas general entities + can only be used within your document, parameter entities can + only be used within an <link + linkend="xml-primer-xml-escape">XML + context</link>.</para> + + <para>Parameter entities are defined in a similar way to general + entities. However, instead of using + <literal>&<replaceable>entity-name</replaceable>;</literal> + to refer to them, use + <literal>%<replaceable>entity-name</replaceable>;</literal> + <footnote><para><emphasis>P</emphasis>arameter entities use + the <emphasis>P</emphasis>ercent + symbol.</para></footnote>. The definition also includes + the <literal>%</literal> between the <literal>ENTITY</literal> + keyword and the name of the entity.</para> + + <example> + <title>Defining Parameter Entities</title> + + <programlisting><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" [ +<!ENTITY % param.some "some"> +<!ENTITY % param.text "text"> +<!ENTITY % param.new "%param.some more %param.text"> +]>]]></programlisting> + </example> + + <para>This may not seem particularly useful. It will be.</para> + </sect2> + + <sect2> + <title>For You to Do…</title> + + <procedure> + <step> + <para>Add a general entity to + <filename>example.xml</filename>.</para> + + <programlisting><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" [ +<!ENTITY version "1.1"> +]> + +<html xmlns="http://www.w3.org/1999/xhtml"> + <head> + <title>An Example XHTML File</title> + </head> + + <body> + <p>This is a paragraph containing some text.</p> + + <p>This paragraph contains some more text.</p> + + <p align="right">This paragraph might be right-justified.</p> + + <p>The current version of this document is: &version;</p> + </body> +</html>]]></programlisting> + </step> + + <step> + <para>Validate the document using + <command>xmllint</command>.</para> + </step> + + <step> + <para>Load <filename>example.xml</filename> into your web + browser (you may need to copy it to + <filename>example.html</filename> before your browser + recognizes it as an XHTML document).</para> + + <para>Unless your browser is very advanced, you will not see + the entity reference <literal>&version;</literal> + replaced with the version number. Most web browsers have + very simplistic parsers which do not handle XML DTD + constructs. Furthermore, the closing <literal>]<</literal> + of the XML context are not recognized properly by browser and + will probably be rendered.</para> + </step> + + <step> + <para>The solution is to <emphasis>normalize</emphasis> your + document using an XML normalizer. The normalizer reads + in valid XML and outputs equally valid XML which has + been transformed in some way. One of the ways in which + the normalizer transforms the XML is to expand all the + entity references in the document, replacing the entities + with the text that they represent.</para> + + <para>You can use <command>xmllint</command> to do + this. It also has an option to drop the initial + DTD section so that the closing <literal>]<</literal> + does not confuse browsers:</para> + + <screen>&prompt.user; <userinput>xmllint --noent --dropdtd example.xml > example.html</userinput></screen> + + <para>You should find a normalized (i.e., entity references + expanded) copy of your document in + <filename>example.html</filename>, ready to load into your + web browser.</para> + </step> + </procedure> + </sect2> + </sect1> + + <sect1 id="xml-primer-include"> + <title>Using Entities to Include Files</title> + + <para>Entities (both + <link linkend="xml-primer-general-entities">general</link> and + <link linkend="xml-primer-parameter-entities">parameter</link>) + are particularly useful when used to include one file inside + another.</para> + + <sect2 id="xml-primer-include-using-gen-entities"> + <title>Using General Entities to Include Files</title> + + <para>Suppose you have some content for an XML book organized + into files, one file per chapter, called + <filename>chapter1.xml</filename>, + <filename>chapter2.xml</filename>, and so forth, with a + <filename>book.xml</filename> file that will contain these + chapters.</para> + + <para>In order to use the contents of these files as the values + for your entities, you declare them with the + <literal>SYSTEM</literal> keyword. This directs the XML + parser to use the contents of the named file as the value of + the entity.</para> + + <example> + <title>Using General Entities to Include Files</title> + + <programlisting><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" [ +<!ENTITY chapter.1 SYSTEM "chapter1.xml"> +<!ENTITY chapter.2 SYSTEM "chapter2.xml"> +<!ENTITY chapter.3 SYSTEM "chapter3.xml"> +]> + +<html xmlns="http://www.w3.org/1999/xhtml"> + &chapter.1; + &chapter.2; + &chapter.3; +</html>]]></programlisting> + </example> + + <warning> + <para>When using general entities to include other files + within a document, the files being included + (<filename>chapter1.xml</filename>, + <filename>chapter2.xml</filename>, and so on) + <emphasis>must not</emphasis> start with a DOCTYPE + declaration. This is a syntax error because entities + are low-level constructs and they are resolved before + any parsing happens.</para> + </warning> + </sect2> + + <sect2> + <title>Using Parameter Entities to Include Files</title> + + <para>Recall that parameter entities can only be used inside an + XML context. Why then would you want to include a file + within an XML context?</para> + + <para>You can use this to ensure that you can reuse your general + entities.</para> + + <para>Suppose that you had many chapters in your document, and + you reused these chapters in two different books, each book + organizing the chapters in a different fashion.</para> + + <para>You could list the entities at the top of each book, but + this quickly becomes cumbersome to manage.</para> + + <para>Instead, place the general entity definitions inside one + file, and use a parameter entity to include that file within + your document.</para> + + <example> + <title>Using Parameter Entities to Include Files</title> + + <para>First, place your entity definitions in a separate file, + called <filename>chapters.ent</filename>. This file + contains the following:</para> + + <programlisting><![CDATA[<!ENTITY chapter.1 SYSTEM "chapter1.xml"> +<!ENTITY chapter.2 SYSTEM "chapter2.xml"> +<!ENTITY chapter.3 SYSTEM "chapter3.xml">]]></programlisting> + + <para>Now create a parameter entity to refer to the contents + of the file. Then use the parameter entity to load the file + into the document, which will then make all the general + entities available for use. Then use the general entities + as before:</para> + + <programlisting><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" [ +<!ENTITY % chapters SYSTEM "chapters.ent"> +%chapters; +]> + +<html xmlns="http://www.w3.org/1999/xhtml"> + &chapter.1; + &chapter.2; + &chapter.3; +</html>]]></programlisting> + </example> + </sect2> + + <sect2> + <title>For You to Do…</title> + + <sect3> + <title>Use General Entities to Include Files</title> + + <procedure> + <step> + <para>Create three files, <filename>para1.xml</filename>, + <filename>para2.xml</filename>, and + <filename>para3.xml</filename>.</para> + + <para>Put content similar to the following in each + file:</para> + + <programlisting><![CDATA[<p>This is the first paragraph.</p>]]></programlisting> + </step> + + <step> + <para>Edit <filename>example.xml</filename> so that it + looks like this:</para> + + <programlisting><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" [ +<!ENTITY version "1.1"> +<!ENTITY para1 SYSTEM "para1.xml"> +<!ENTITY para2 SYSTEM "para2.xml"> +<!ENTITY para3 SYSTEM "para3.xml"> +]> + +<html xmlns="http://www.w3.org/1999/xhtml"> + <head> + <title>An Example XHTML File</title> + </head> + + <body> + <p>The current version of this document is: &version;</p> + + ¶1; + ¶2; + ¶3; + </body> +</html>]]></programlisting> + </step> + + <step> + <para>Produce <filename>example.html</filename> by + normalizing <filename>example.xml</filename>.</para> + + <screen>&prompt.user; <userinput>xmllint --dropdtd --noent example.xml > example.html</userinput></screen> + </step> + + <step> + <para>Load <filename>example.html</filename> into your web + browser, and confirm that the + <filename>para<replaceable>n</replaceable>.xml</filename> + files have been included in + <filename>example.html</filename>.</para> + </step> + </procedure> + </sect3> + + <sect3> + <title>Use Parameter Entities to Include Files</title> + + <note> + <para>You must have taken the previous steps first.</para> + </note> + + <procedure> + <step> + <para>Edit <filename>example.xml</filename> so that it + looks like this:</para> + + <programlisting><![CDATA[<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" +"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" [ +<!ENTITY % entities SYSTEM "entities.ent"> %entities; +]> + +<html xmlns="http://www.w3.org/1999/xhtml"> + <head> + <title>An Example XHTML File</title> + </head> + + <body> + <p>The current version of this document is: &version;</p> + + ¶1; + ¶2; + ¶3; + </body> +</html>]]></programlisting> + </step> + + <step> + <para>Create a new file, + <filename>entities.ent</filename>, with this + content:</para> + + <programlisting><![CDATA[<!ENTITY version "1.1"> +<!ENTITY para1 SYSTEM "para1.xml"> +<!ENTITY para2 SYSTEM "para2.xml"> +<!ENTITY para3 SYSTEM "para3.xml">]]></programlisting> + </step> + + <step> + <para>Produce <filename>example.html</filename> by + normalizing <filename>example.xml</filename>.</para> + + <screen>&prompt.user; <userinput>xmllint --dropdtd --noent example.xml > example.html</userinput></screen> + </step> + + <step> + <para>Load <filename>example.html</filename> into your web + browser, and confirm that the + <filename>para<replaceable>n</replaceable>.xml</filename> + files have been included in + <filename>example.html</filename>.</para> + </step> + </procedure> + </sect3> + </sect2> + </sect1> + + <sect1 id="xml-primer-marked-sections"> + <title>Marked Sections</title> + + <para>XML provides a mechanism to indicate that particular pieces + of the document should be processed in a special way. These are + termed <quote>marked sections</quote>.</para> + + <example> + <title>Structure of A Marked Section</title> + + <programlisting><![<replaceable>KEYWORD</replaceable>[ + Contents of marked section +]]></programlisting> + </example> + + <para>As you would expect, being an XML construct, a marked + section starts with <literal><!</literal>.</para> + + <para>The first square bracket begins to delimit the marked + section.</para> + + <para><replaceable>KEYWORD</replaceable> describes how this marked + section should be processed by the parser.</para> + + <para>The second square bracket indicates that the content of the + marked section starts here.</para> + + <para>The marked section is finished by closing the two square + brackets, and then returning to the document context from the + XGML context with <literal>></literal>.</para> + + <sect2> + <title>Marked Section Keywords</title> + + <sect3> + <title><literal>CDATA</literal></title> + + <para>These keywords denote the marked sections + <emphasis>content model</emphasis>, and allow you to change + it from the default.</para> + + <para>When an XML parser is processing a document it keeps + track of what is called the <quote>content + model</quote>.</para> + + <para>Briefly, the content model describes what sort of + content the parser is expecting to see, and what it will do + with it when it finds it.</para> + + <para>The content model you will probably find most + useful is <literal>CDATA</literal>.</para> + + <para><literal>CDATA</literal> is for <quote>Character + Data</quote>. If the parser is in this content model then + it is expecting to see characters, and characters only. In + this model the <literal><</literal> and + <literal>&</literal> symbols lose their special status, + and will be treated as ordinary characters.</para> + + <note> + <para>When you use <literal>CDATA</literal> + in examples of text marked up in + XML, keep in mind that the content of + <literal>CDATA</literal> is not validated. You have to + check the included XML text using other means. You + could, for example, write the example in another document, + validate the example code, and then paste it to your + <literal>CDATA</literal> content.</para> + </note> + + <!-- The nesting of CDATA within the next example is disgusting --> + <example> + <title>Using a <literal>CDATA</literal> Marked + Section</title> + + <programlisting><para>Here is an example of how you would include some text + that contained many <literal>&lt;</literal> + and <literal>&amp;</literal> symbols. The sample + text is a fragment of XHTML. The surrounding text (<para> and + <programlisting>) are from DocBook.</para> + +<programlisting> + <![CDATA[<![CDATA[ + <p>This is a sample that shows you some of the elements within + XHTML. Since the angle brackets are used so many times, it is + simpler to say the whole example is a CDATA marked section + than to use the entity names for the left and right angle + brackets throughout.</p> + + <ul> + <li>This is a listitem</li> + <li>This is a second listitem</li> + <li>This is a third listitem</li> + </ul> + + <p>This is the end of the example.</p>]]> + ]]> +</programlisting></programlisting> + + <para>If you look at the source for this document you will + see this technique used throughout.</para> + </example> + </sect3> + + <sect3> + <title><literal>INCLUDE</literal> and + <literal>IGNORE</literal></title> + + <para>If the keyword is <literal>INCLUDE</literal> then the + contents of the marked section will be processed. If the + keyword is <literal>IGNORE</literal> then the marked section + is ignored and will not be processed. It will not appear in + the output.</para> + + <example> + <title>Using <literal>INCLUDE</literal> and + <literal>IGNORE</literal> in Marked Sections</title> + + <programlisting><![INCLUDE[ + This text will be processed and included. +]]> + +<![IGNORE[ + This text will not be processed or included. +]]></programlisting> + </example> + + <para>By itself, this is not too useful. If you wanted to + remove text from your document you could cut it out, or wrap + it in comments.</para> + + <para>It becomes more useful when you realize you can use + <link linkend="xml-primer-parameter-entities">parameter + entities</link> to control this, yet this usage is limited + to entity files.</para> + + <para>For example, suppose that you produced a hard-copy + version of some documentation and an electronic version. In + the electronic version you wanted to include some extra + content that was not to appear in the hard-copy.</para> + + <para>Create an entity file that defines general entities + to include each chapter and guard these definitions with + a parameter entity that can be set to either + <literal>INCLUDE</literal> or <literal>IGNORE</literal> + to control whether the entity is defined. After these + conditional general entity definitions, place one more + definition for each general entity to set them to an + empty value. This technique makes use of the fact that + entity definitions cannot be overridden but always the + first definition takes effect. So you can control the + inclusion of your chapter with the corrsponding parameter + entity; if you set it to <literal>INCLUDE</literal>, the + first general entity definition will be read and the + second one will be ignored but if you set it to + <literal>IGNORE</literal>, the first definition will be + ignored and the second one will take effect.</para> + + <example> + <title>Using A Parameter Entity to Control a Marked + Section</title> + + <programlisting> +<!ENTITY % electronic.copy "INCLUDE"> + +<![%electronic.copy;[ +<!ENTITY chap.preface SYSTEM "preface.xml"> +]]> + +<!ENTITY chap.preface ""> +</programlisting> + + <para>When producing the hard-copy version, change the + parameter entity's definition to:</para> + + <programlisting><!ENTITY % electronic.copy "IGNORE"></programlisting> + </example> + </sect3> + </sect2> + + <sect2> + <title>For You to Do…</title> + + <procedure> + <step> + <para>Modify the <filename>entities.ent</filename> file to contain + the following:</para> + + <programlisting><!ENTITY version "1.1"> +<!ENTITY % conditional.text "IGNORE"> + +<![%conditional.text;[ +<!ENTITY para1 SYSTEM "para1.xml"> +]]> + +<!ENTITY para1 ""> + +<!ENTITY para2 SYSTEM "para2.xml"> +<!ENTITY para3 SYSTEM "para3.xml"></programlisting> + </step> + + <step> + <para>Normalize the <filename>example.xml</filename> file and notice + that the conditional text is not present on the output document. + Now if you set the parameter entity guard to <literal>INCLUDE</literal> + and regenerate the normalized document, it will appear there again. + Of course, this method makes more sense if you have more conditional + chunks that depend on the same condition, for example, whether you are + generating printed or online text.</para> + </step> + </procedure> + </sect2> + </sect1> + + <sect1 id="xml-primer-conclusion"> + <title>Conclusion</title> + + <para>That is the conclusion of this XML primer. For reasons of + space and complexity several things have not been covered in + depth (or at all). However, the previous sections cover enough + XML for you to be able to follow the organization of the FDP + documentation.</para> + </sect1> +</chapter> diff --git a/en_US.ISO8859-1/books/handbook/Makefile b/en_US.ISO8859-1/books/handbook/Makefile index f2e41fc06f..fa7ad27323 100644 --- a/en_US.ISO8859-1/books/handbook/Makefile +++ b/en_US.ISO8859-1/books/handbook/Makefile @@ -39,8 +39,6 @@ DOC?= book FORMATS?= html-split -HAS_INDEX= true - INSTALL_COMPRESSED?= gz INSTALL_ONLY_COMPRESSED?= diff --git a/en_US.ISO8859-1/books/handbook/bibliography/chapter.xml b/en_US.ISO8859-1/books/handbook/bibliography/chapter.xml index 2b7bdece60..da614bdf17 100644 --- a/en_US.ISO8859-1/books/handbook/bibliography/chapter.xml +++ b/en_US.ISO8859-1/books/handbook/bibliography/chapter.xml @@ -532,7 +532,7 @@ <ulink url="http://www.FreeBSD.org/cgi/cvsweb.cgi/src/share/misc/bsd-family-tree"></ulink> or - <ulink type="html" + <ulink url="file://localhost/usr/share/misc/bsd-family-tree"><filename>/usr/share/misc/bsd-family-tree</filename></ulink> on a FreeBSD machine.</para> </listitem> diff --git a/en_US.ISO8859-1/books/handbook/book.xml b/en_US.ISO8859-1/books/handbook/book.xml index e23d7ec009..59144256ac 100644 --- a/en_US.ISO8859-1/books/handbook/book.xml +++ b/en_US.ISO8859-1/books/handbook/book.xml @@ -295,7 +295,7 @@ &chap.eresources; &chap.pgpkeys; </part> - &freebsd-glossary; + &chap.freebsd-glossary; &chap.index; &chap.colophon; </book> diff --git a/en_US.ISO8859-1/books/handbook/chapters.ent b/en_US.ISO8859-1/books/handbook/chapters.ent index d5cd395e7f..0bcc64c5d7 100644 --- a/en_US.ISO8859-1/books/handbook/chapters.ent +++ b/en_US.ISO8859-1/books/handbook/chapters.ent @@ -63,7 +63,7 @@ <!ENTITY chap.eresources.www.index.inc SYSTEM "eresources.xml.www.index.inc"> <!ENTITY chap.eresources.www.inc SYSTEM "eresources.xml.www.inc"> <!ENTITY chap.pgpkeys SYSTEM "pgpkeys/chapter.xml"> - <!ENTITY chap.freebsd-glossary "&freebsd-glossary;"> - <!ENTITY chap.index SYSTEM "index.xml"> + <!ENTITY chap.freebsd-glossary SYSTEM "../../share/xml/glossary.ent"> + <!ENTITY chap.index "<index xmlns='http://docbook.org/ns/docbook'/>"> <!ENTITY chap.colophon SYSTEM "colophon.xml"> diff --git a/en_US.ISO8859-1/books/handbook/colophon.xml b/en_US.ISO8859-1/books/handbook/colophon.xml index 0d93d9bb66..c583ddfe90 100644 --- a/en_US.ISO8859-1/books/handbook/colophon.xml +++ b/en_US.ISO8859-1/books/handbook/colophon.xml @@ -12,7 +12,7 @@ from XML into many different presentation formats using XSLT. The printed version of this document would not be possible without Donald Knuth's - <application>&tex;</application> typesetting language, Leslie + &tex; typesetting language, Leslie Lamport's <application>LaTeX</application>, or Sebastian Rahtz's <application>JadeTeX</application> macro package.</para> </colophon> diff --git a/en_US.ISO8859-1/books/handbook/introduction/chapter.xml b/en_US.ISO8859-1/books/handbook/introduction/chapter.xml index afbe796fcf..9adbd535d2 100644 --- a/en_US.ISO8859-1/books/handbook/introduction/chapter.xml +++ b/en_US.ISO8859-1/books/handbook/introduction/chapter.xml @@ -1185,7 +1185,7 @@ <term>The FreeBSD Handbook</term> <listitem> - <para><ulink type="html" + <para><ulink url="file://localhost/usr/local/share/doc/freebsd/handbook/index.html"><filename>/usr/local/share/doc/freebsd/handbook/index.html</filename></ulink></para> </listitem> </varlistentry> @@ -1194,7 +1194,7 @@ <term>The FreeBSD FAQ</term> <listitem> - <para><ulink type="html" + <para><ulink url="file://localhost/usr/local/share/doc/freebsd/faq/index.html"><filename>/usr/local/share/doc/freebsd/faq/index.html</filename></ulink></para> </listitem> </varlistentry> diff --git a/en_US.ISO8859-1/books/handbook/mirrors/chapter.xml b/en_US.ISO8859-1/books/handbook/mirrors/chapter.xml index ba2dde8e6b..f46b6db93e 100644 --- a/en_US.ISO8859-1/books/handbook/mirrors/chapter.xml +++ b/en_US.ISO8859-1/books/handbook/mirrors/chapter.xml @@ -899,7 +899,6 @@ Certificate information: by a configuration file called the <filename>supfile</filename>. There are some sample <filename>supfiles</filename> in the directory <ulink - type="html" url="file://localhost/usr/share/examples/cvsup/"><filename>/usr/share/examples/cvsup/</filename></ulink>.</para> <para>The information in a <filename>supfile</filename> answers diff --git a/en_US.ISO8859-1/books/handbook/users/Makefile b/en_US.ISO8859-1/books/handbook/users/Makefile new file mode 100644 index 0000000000..b44bd80628 --- /dev/null +++ b/en_US.ISO8859-1/books/handbook/users/Makefile @@ -0,0 +1,15 @@ +# +# Build the Handbook with just the content from this chapter. +# +# $FreeBSD$ +# + +CHAPTERS= users/chapter.xml + +VPATH= .. + +MASTERDOC= ${.CURDIR}/../${DOC}.${DOCBOOKSUFFIX} + +DOC_PREFIX?= ${.CURDIR}/../../../.. + +.include "../Makefile" diff --git a/en_US.ISO8859-1/books/handbook/users/chapter.xml b/en_US.ISO8859-1/books/handbook/users/chapter.xml new file mode 100644 index 0000000000..39f145021d --- /dev/null +++ b/en_US.ISO8859-1/books/handbook/users/chapter.xml @@ -0,0 +1,1043 @@ +<?xml version="1.0" encoding="iso-8859-1"?> +<!-- + The FreeBSD Documentation Project + + $FreeBSD$ +--> + +<chapter id="users"> + <chapterinfo> + <authorgroup> + <author> + <firstname>Neil</firstname> + <surname>Blakey-Milner</surname> + <contrib>Contributed by </contrib> + </author> + </authorgroup> + <!-- Feb 2000 --> + </chapterinfo> + + <title>Users and Basic Account Management</title> + + <sect1 id="users-synopsis"> + <title>Synopsis</title> + + <para>&os; allows multiple users to use the computer at the same + time. While only one user can sit in front of the screen and + use the keyboard at any one time, any number of users can log + in to the system through the network. To use the system, every + user must have a user account.</para> + + <para>After reading this chapter, you will know:</para> + + <itemizedlist> + <listitem> + <para>The differences between the various user accounts on a + &os; system.</para> + </listitem> + + <listitem> + <para>How to add and remove user accounts.</para> + </listitem> + + <listitem> + <para>How to change account details, such as the user's full + name or preferred shell.</para> + </listitem> + + <listitem> + <para>How to set limits on a per-account basis to control the + resources, such as memory and CPU time, that accounts and + groups of accounts are allowed to access.</para> + </listitem> + + <listitem> + <para>How to use groups to make account management + easier.</para> + </listitem> + </itemizedlist> + + <para>Before reading this chapter, you should:</para> + + <itemizedlist> + <listitem> + <para>Understand the <link linkend="basics">basics of &unix; + and &os;</link>.</para> + </listitem> + </itemizedlist> + </sect1> + + <sect1 id="users-introduction"> + <title>Introduction</title> + + <para>Since all access to the &os; system is achieved via accounts + and all processes are run by users, user and account management + is important.</para> + + <para>Every account on a &os; system has certain information + associated with it to identify the account.</para> + + <variablelist> + <varlistentry> + <term>User name</term> + + <listitem> + <para>The user name is typed at the <prompt>login:</prompt> + prompt. User names must be unique on the system as no two + users can have the same user name. There are a number of + rules for creating valid user names, documented in + &man.passwd.5;. Typically user names consist of eight or + fewer all lower case characters in order to maintain + backwards compatibility with applications.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Password</term> + + <listitem> + <para>Each account has an associated password. While the + password can be blank, this is highly discouraged and + every account should have a password.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>User ID (<acronym>UID</acronym>)</term> + + <listitem> + <para>The User ID (<acronym>UID</acronym>) is a number, + traditionally from 0 to 65535<footnote + id="users-largeuidgid"> + <para>It is possible to use + <acronym>UID</acronym>s/<acronym>GID</acronym>s as + large as 4294967295, but such IDs can cause serious + problems with software that makes assumptions about + the values of IDs.</para> + </footnote>, used to uniquely identify the user to the + system. Internally, &os; uses the + <acronym>UID</acronym> to identify users. Commands that + allow a user name to be specified will first convert it to + the <acronym>UID</acronym>. Though unlikely, it is + possible for several accounts with different user names to + share the same <acronym>UID</acronym>. As far as &os; is + concerned, these accounts are one user.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Group ID (<acronym>GID</acronym>)</term> + + <listitem> + <para>The Group ID (<acronym>GID</acronym>) is a number, + traditionally from 0 to 65535<footnoteref + linkend="users-largeuidgid"/>, used to uniquely identify + the primary group that the user belongs to. Groups are a + mechanism for controlling access to resources based on a + user's <acronym>GID</acronym> rather than their + <acronym>UID</acronym>. This can significantly reduce the + size of some configuration files. A user may also be a + member of more than one group.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Login class</term> + + <listitem> + <para>Login classes are an extension to the group mechanism + that provide additional flexibility when tailoring the + system to different users.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Password change time</term> + + <listitem> + <para>By default &os; does not force users to change their + passwords periodically. Password expiration can be + enforced on a per-user basis, forcing some or all users to + change their passwords after a certain amount of time has + elapsed.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Account expiry time</term> + + <listitem> + <para>By default &os; does not expire accounts. When + creating accounts that need a limited lifespan, such as + student accounts in a school, specify the account expiry + date. After the expiry time has elapsed, the account + cannot be used to log in to the system, although the + account's directories and files will remain.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>User's full name</term> + + <listitem> + <para>The user name uniquely identifies the account to &os;, + but does not necessarily reflect the user's real name. + This information can be associated with the + account.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>Home directory</term> + + <listitem> + <para>The home directory is the full path to a directory on + the system. This is the user's starting directory when + the user logs in. A common convention is to put all user + home directories under <filename + class="directory">/home/<replaceable>username</replaceable></filename> + or <filename + class="directory">/usr/home/<replaceable>username</replaceable></filename>. + Each user stores their personal files and subdirectories + in their own home directory.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term>User shell</term> + + <listitem> + <para>The shell provides the default environment users use + to interact with the system. There are many different + kinds of shells, and experienced users will have their own + preferences, which can be reflected in their account + settings.</para> + </listitem> + </varlistentry> + </variablelist> + + <para>There are three main types of accounts: the <link + linkend="users-superuser">superuser</link>, <link + linkend="users-system">system accounts</link>, and <link + linkend="users-user">user accounts</link>. The superuser + account, usually called <username>root</username>, is used to + manage the system with no limitations on privileges. System + accounts are used to run services. User accounts are + assigned to real people and are used to log in and use the + system.</para> + + <sect2 id="users-superuser"> + <title>The Superuser Account</title> + + <indexterm> + <primary>accounts</primary> + <secondary>superuser (root)</secondary> + </indexterm> + <para>The superuser account, usually called + <username>root</username>, is used to perform system + administration tasks and should not be used for day-to-day + tasks like sending and receiving mail, general exploration of + the system, or programming.</para> + + <para>This is because the superuser, unlike normal user + accounts, can operate without limits, and misuse of the + superuser account may result in spectacular disasters. User + accounts are unable to destroy the system by mistake, so it is + generally best to use normal user accounts whenever possible, + unless extra privilege is required.</para> + + <para>Always double and triple-check any commands issued as the + superuser, since an extra space or missing character can mean + irreparable data loss.</para> + + <para>Always create a user account for the system administrator + and use this account to log in to the system for general + usage. This applies equally to multi-user or single-user + systems. Later sections will discuss how to create additional + accounts and how to change between the normal user and + superuser.</para> + </sect2> + + <sect2 id="users-system"> + <title>System Accounts</title> + + <indexterm> + <primary>accounts</primary> + <secondary>system</secondary> + </indexterm> + <para>System accounts are used to run services such as DNS, + mail, and web servers. The reason for this is security; if + all services ran as the superuser, they could act without + restriction.</para> + + <indexterm> + <primary>accounts</primary> + <secondary><username>daemon</username></secondary> + </indexterm> + <indexterm> + <primary>accounts</primary> + <secondary><username>operator</username></secondary> + </indexterm> + <para>Examples of system accounts are + <username>daemon</username>, <username>operator</username>, + <username>bind</username>, <username>news</username>, and + <username>www</username>.</para> + + <indexterm> + <primary>accounts</primary> + <secondary><username>nobody</username></secondary> + </indexterm> + <para><username>nobody</username> is the generic unprivileged + system account. However, the more services that use + <username>nobody</username>, the more files and processes that + user will become associated with, and hence the more + privileged that user becomes.</para> + </sect2> + + <sect2 id="users-user"> + <title>User Accounts</title> + + <indexterm> + <primary>accounts</primary> + <secondary>user</secondary> + </indexterm> + <para>User accounts are the primary means of access for real + people to the system. User accounts insulate the user and + the environment, preventing users from damaging the system + or other users, and allowing users to customize their + environment without affecting others.</para> + + <para>Every person accessing the system should have a unique + user account. This allows the administrator to find out who + is doing what, prevents users from clobbering each others' + settings or reading each others' mail, and so forth.</para> + + <para>Each user can set up their own environment to accommodate + their use of the system, by using alternate shells, editors, + key bindings, and language.</para> + </sect2> + </sect1> + + <sect1 id="users-modifying"> + <title>Modifying Accounts</title> + + <indexterm> + <primary>accounts</primary> + <secondary>modifying</secondary> + </indexterm> + + <para>&os; provides a variety of different commands to manage + user accounts. The most common commands are summarized below, + followed by more detailed examples of their usage.</para> + + <informaltable frame="none" pgwide="1"> + <tgroup cols="2"> + <colspec colwidth="1*"/> + <colspec colwidth="2*"/> + + <thead> + <row> + <entry>Command</entry> + <entry>Summary</entry> + </row> + </thead> + <tbody> + <row> + <entry>&man.adduser.8;</entry> + <entry>The recommended command-line application for adding + new users.</entry> + </row> + + <row> + <entry>&man.rmuser.8;</entry> + <entry>The recommended command-line application for + removing users.</entry> + </row> + + <row> + <entry>&man.chpass.1;</entry> + <entry>A flexible tool for changing user database + information.</entry> + </row> + + <row> + <entry>&man.passwd.1;</entry> + <entry>The simple command-line tool to change user + passwords.</entry> + </row> + + <row> + <entry>&man.pw.8;</entry> + <entry>A powerful and flexible tool for modifying all + aspects of user accounts.</entry> + </row> + </tbody> + </tgroup> + </informaltable> + + <sect2 id="users-adduser"> + <title><command>adduser</command></title> + + <indexterm> + <primary>accounts</primary> + <secondary>adding</secondary> + </indexterm> + <indexterm> + <primary><command>adduser</command></primary> + </indexterm> + <indexterm> + <primary><filename + class="directory">/usr/share/skel</filename></primary> + </indexterm> + <indexterm><primary>skeleton directory</primary></indexterm> + <para>&man.adduser.8; is a simple program for adding new users + When a new user is added, this program automatically updates + <filename>/etc/passwd</filename> and + <filename>/etc/group</filename>. It also creates a home + directory for the new user, copies in the default + configuration files from <filename + class="directory">/usr/share/skel</filename>, and can + optionally mail the new user a welcome message.</para> + + <example> + <title>Adding a User on &os;</title> + + <screen>&prompt.root; <userinput>adduser</userinput> +Username: <userinput>jru</userinput> +Full name: <userinput>J. Random User</userinput> +Uid (Leave empty for default): +Login group [jru]: +Login group is jru. Invite jru into other groups? []: <userinput>wheel</userinput> +Login class [default]: +Shell (sh csh tcsh zsh nologin) [sh]: <userinput>zsh</userinput> +Home directory [/home/jru]: +Home directory permissions (Leave empty for default): +Use password-based authentication? [yes]: +Use an empty password? (yes/no) [no]: +Use a random password? (yes/no) [no]: +Enter password: +Enter password again: +Lock out the account after creation? [no]: +Username : jru +Password : **** +Full Name : J. Random User +Uid : 1001 +Class : +Groups : jru wheel +Home : /home/jru +Shell : /usr/local/bin/zsh +Locked : no +OK? (yes/no): <userinput>yes</userinput> +adduser: INFO: Successfully added (jru) to the user database. +Add another user? (yes/no): <userinput>no</userinput> +Goodbye! +&prompt.root;</screen> + </example> + + <note> + <para>Since the password is not echoed when typed, be careful + to not mistype the password when creating the user + account.</para> + </note> + </sect2> + + <sect2 id="users-rmuser"> + <title><command>rmuser</command></title> + + <indexterm><primary><command>rmuser</command></primary></indexterm> + <indexterm> + <primary>accounts</primary> + <secondary>removing</secondary> + </indexterm> + + <para>To completely remove a user from the system use + &man.rmuser.8;. This command performs the following + steps:</para> + + <procedure> + <step> + <para>Removes the user's &man.crontab.1; entry if one + exists.</para> + </step> + + <step> + <para>Removes any &man.at.1; jobs belonging to the + user.</para> + </step> + + <step> + <para>Kills all processes owned by the user.</para> + </step> + + <step> + <para>Removes the user from the system's local password + file.</para> + </step> + + <step> + <para>Removes the user's home directory, if it is owned by + the user.</para> + </step> + + <step> + <para>Removes the incoming mail files belonging to the user + from <filename + class="directory">/var/mail</filename>.</para> + </step> + + <step> + <para>Removes all files owned by the user from temporary + file storage areas such as <filename + class="directory">/tmp</filename>.</para> + </step> + + <step> + <para>Finally, removes the username from all groups to which + it belongs in <filename>/etc/group</filename>.</para> + + <note> + <para>If a group becomes empty and the group name is the + same as the username, the group is removed. This + complements the per-user unique groups created by + &man.adduser.8;.</para> + </note> + </step> + </procedure> + + <para>&man.rmuser.8; cannot be used to remove superuser + accounts since that is almost always an indication of massive + destruction.</para> + + <para>By default, an interactive mode is used, as shown + in the following example.</para> + + <example> + <title><command>rmuser</command> Interactive Account + Removal</title> + + <screen>&prompt.root; <userinput>rmuser jru</userinput> +Matching password entry: +jru:*:1001:1001::0:0:J. Random User:/home/jru:/usr/local/bin/zsh +Is this the entry you wish to remove? <userinput>y</userinput> +Remove user's home directory (/home/jru)? <userinput>y</userinput> +Updating password file, updating databases, done. +Updating group file: trusted (removing group jru -- personal group is empty) done. +Removing user's incoming mail file /var/mail/jru: done. +Removing files belonging to jru from /tmp: done. +Removing files belonging to jru from /var/tmp: done. +Removing files belonging to jru from /var/tmp/vi.recover: done. +&prompt.root;</screen> + </example> + </sect2> + + <sect2 id="users-chpass"> + <title><command>chpass</command></title> + + <indexterm><primary><command>chpass</command></primary></indexterm> + <para>&man.chpass.1; can be used to change user database + information such as passwords, shells, and personal + information.</para> + + <para>Only the superuser can change other users' information and + passwords with &man.chpass.1;.</para> + + <para>When passed no options, aside from an optional username, + &man.chpass.1; displays an editor containing user information. + When the user exists from the editor, the user database is + updated with the new information.</para> + + <note> + <para>You will be asked for your password after exiting the + editor if you are not the superuser.</para> + </note> + + <example> + <title>Interactive <command>chpass</command> by + Superuser</title> + + <screen>#Changing user database information for jru. +Login: jru +Password: * +Uid [#]: 1001 +Gid [# or name]: 1001 +Change [month day year]: +Expire [month day year]: +Class: +Home directory: /home/jru +Shell: /usr/local/bin/zsh +Full Name: J. Random User +Office Location: +Office Phone: +Home Phone: +Other information:</screen> + </example> + + <para>A user can change only a small subset of this + information, and only for their own user account.</para> + + <example> + <title>Interactive <command>chpass</command> by Normal + User</title> + + <screen>#Changing user database information for jru. +Shell: /usr/local/bin/zsh +Full Name: J. Random User +Office Location: +Office Phone: +Home Phone: +Other information:</screen> + </example> + + <note> + <para>&man.chfn.1; and &man.chsh.1; are links to + &man.chpass.1;, as are &man.ypchpass.1;, &man.ypchfn.1;, and + &man.ypchsh.1;. <acronym>NIS</acronym> support is + automatic, so specifying the <literal>yp</literal> before + the command is not necessary. How to configure NIS is + covered in <xref linkend="network-servers"/>.</para> + </note> + </sect2> + <sect2 id="users-passwd"> + <title><command>passwd</command></title> + + <indexterm><primary><command>passwd</command></primary></indexterm> + <indexterm> + <primary>accounts</primary> + <secondary>changing password</secondary> + </indexterm> + <para>&man.passwd.1; is the usual way to change your own + password as a user, or another user's password as the + superuser.</para> + + <note> + <para>To prevent accidental or unauthorized changes, the user + must enter their original password before a new password can + be set. This is not the case when the superuser changes a + user's password.</para> + </note> + + <example> + <title>Changing Your Password</title> + + <screen>&prompt.user; <userinput>passwd</userinput> +Changing local password for jru. +Old password: +New password: +Retype new password: +passwd: updating the database... +passwd: done</screen> + </example> + + <example> + <title>Changing Another User's Password as the + Superuser</title> + + <screen>&prompt.root; <userinput>passwd jru</userinput> +Changing local password for jru. +New password: +Retype new password: +passwd: updating the database... +passwd: done</screen> + </example> + + <note> + <para>As with &man.chpass.1;, &man.yppasswd.1; is a link to + &man.passwd.1;, so NIS works with either command.</para> + </note> + </sect2> + + + <sect2 id="users-pw"> + <title><command>pw</command></title> + + <indexterm><primary><command>pw</command></primary></indexterm> + + <para>&man.pw.8; is a command line utility to create, remove, + modify, and display users and groups. It functions as a front + end to the system user and group files. &man.pw.8; has a very + powerful set of command line options that make it suitable for + use in shell scripts, but new users may find it more + complicated than the other commands presented in this + section.</para> + </sect2> + + + </sect1> + + <sect1 id="users-limiting"> + <title>Limiting Users</title> + + <indexterm><primary>limiting users</primary></indexterm> + <indexterm> + <primary>accounts</primary> + <secondary>limiting</secondary> + </indexterm> + <para>&os; provides several methods for an administrator to limit + the amount of system resources an individual may use. These + limits are discussed in two sections: disk quotas and other + resource limits.</para> + + <indexterm><primary>quotas</primary></indexterm> + <indexterm> + <primary>limiting users</primary> + <secondary>quotas</secondary> + </indexterm> + <indexterm><primary>disk quotas</primary></indexterm> + <para>Disk quotas limit the amount of disk space available to + users and provide a way to quickly check that usage without + calculating it every time. Quotas are discussed in <xref + linkend="quotas"/>.</para> + + <para>The other resource limits include ways to limit the amount + of CPU, memory, and other resources a user may consume. These + are defined using login classes and are discussed here.</para> + + <indexterm> + <primary><filename>/etc/login.conf</filename></primary> + </indexterm> + <para>Login classes are defined in + <filename>/etc/login.conf</filename> and are described in detail + in &man.login.conf.5;. Each user account is assigned to a login + class, <literal>default</literal> by default, and each login + class has a set of login capabilities associated with it. A + login capability is a + <literal><replaceable>name</replaceable>=<replaceable>value</replaceable></literal> + pair, where <replaceable>name</replaceable> is a well-known + identifier and <replaceable>value</replaceable> is an arbitrary + string which is processed accordingly depending on the + <replaceable>name</replaceable>. Setting up login classes and + capabilities is rather straightforward and is also described in + &man.login.conf.5;.</para> + + <note> + <para>&os; does not normally read the configuration in + <filename>/etc/login.conf</filename> directly, but instead + reads the <filename>/etc/login.conf.db</filename> database + which provides faster lookups. Whenever + <filename>/etc/login.conf</filename> is edited, the + <filename>/etc/login.conf.db</filename> must be updated by + executing the following command:</para> + + <screen>&prompt.root; <userinput>cap_mkdb /etc/login.conf</userinput></screen> + </note> + + <para>Resource limits differ from the default login capabilities + in two ways. First, for every limit, there is a soft (current) + and hard limit. A soft limit may be adjusted by the user or + application, but may not be set higher than the hard limit. The + hard limit may be lowered by the user, but can only be raised + by the superuser. Second, most resource limits apply per + process to a specific user, not to the user as a whole. These + differences are mandated by the specific handling of the limits, + not by the implementation of the login capability + framework.</para> + + <para>Below are the most commonly used resource limits. The rest + of the limits, along with all the other login capabilities, can + be found in &man.login.conf.5;.</para> + + <variablelist> + <varlistentry> + <term><literal>coredumpsize</literal></term> + + <listitem> + <para>The limit on the size of a core file<indexterm><primary>coredumpsize</primary></indexterm> generated by a + program is subordinate to other limits<indexterm><primary>limiting users</primary><secondary>coredumpsize</secondary></indexterm> on disk usage, such + as <literal>filesize</literal>, or disk quotas. + This limit is often used as a less-severe method of + controlling disk space consumption. Since users do not + generate core files themselves, and often do not delete + them, setting this may save them from running out of disk + space should a large program crash.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>cputime</literal></term> + + <listitem> + <para>The maximum amount of CPU<indexterm><primary>cputime</primary></indexterm><indexterm><primary>limiting users</primary><secondary>cputime</secondary></indexterm> time a user's process may + consume. Offending processes will be killed by the + kernel.</para> + + <note> + <para>This is a limit on CPU <emphasis>time</emphasis> + consumed, not percentage of the CPU as displayed in + some fields by &man.top.1; and &man.ps.1;.</para> + </note> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>filesize</literal></term> + + <listitem> + <para>The maximum size of a file<indexterm><primary>filesize</primary></indexterm><indexterm><primary>limiting users</primary><secondary>filesize</secondary></indexterm> the user may own. Unlike + <link linkend="quotas">disk quotas</link>, this limit is + enforced on individual files, not the set of all files a + user owns.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>maxproc</literal></term> + + <listitem> + <para>The maximum number of processes<indexterm><primary>maxproc</primary></indexterm><indexterm><primary>limiting users</primary><secondary>maxproc</secondary></indexterm> a user can run. This + includes foreground and background processes. This limit + may not be larger than the system limit specified by the + <varname>kern.maxproc</varname> &man.sysctl.8;. Setting + this limit too small may hinder a user's productivity as + it is often useful to be logged in multiple times or to + execute pipelines. Some tasks, such as compiling a large + program, spawn multiple processes and other intermediate + preprocessors.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>memorylocked</literal></term> + + <listitem> + <para>The maximum amount of memory<indexterm><primary>memorylocked</primary></indexterm><indexterm><primary>limiting users</primary><secondary>memorylocked</secondary></indexterm> a process may request + to be locked into main memory using &man.mlock.2;. Some + system-critical programs, such as &man.amd.8;, lock into + main memory so that if the system begins to swap, they do + not contribute to disk thrashing.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>memoryuse</literal></term> + + <listitem> + <para>The maximum amount of memory<indexterm><primary>memoryuse</primary></indexterm><indexterm><primary>limiting users</primary><secondary>memoryuse</secondary></indexterm> a process may consume at + any given time. It includes both core memory and swap + usage. This is not a catch-all limit for restricting + memory consumption, but is a good start.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>openfiles</literal></term> + + <listitem> + <para>The maximum number of files a process may have open<indexterm><primary>openfiles</primary></indexterm><indexterm><primary>limiting users</primary><secondary>openfiles</secondary></indexterm>. + In &os;, files are used to represent sockets and IPC + channels, so be careful not to set this too low. The + system-wide limit for this is defined by the + <varname>kern.maxfiles</varname> &man.sysctl.8;.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>sbsize</literal></term> + + <listitem> + <para>The limit on the amount of network memory, and + thus mbufs<indexterm><primary>sbsize</primary></indexterm><indexterm><primary>limiting users</primary><secondary>sbsize</secondary></indexterm>, a user may consume in order to limit network + communications.</para> + </listitem> + </varlistentry> + + <varlistentry> + <term><literal>stacksize</literal></term> + + <listitem> + <para>The maximum size of a process stack<indexterm><primary>stacksize</primary></indexterm><indexterm><primary>limiting users</primary><secondary>stacksize</secondary></indexterm>. This alone is + not sufficient to limit the amount of memory a program + may use so it should be used in conjunction with other + limits.</para> + </listitem> + </varlistentry> + </variablelist> + + <para>There are a few other things to remember when setting + resource limits. Following are some general tips, suggestions, + and miscellaneous comments.</para> + + <itemizedlist> + <listitem> + <para>Processes started at system startup by + <filename>/etc/rc</filename> are assigned to the + <literal>daemon</literal> login class.</para> + </listitem> + + <listitem> + <para>Although the <filename>/etc/login.conf</filename> that + comes with the system is a good source of reasonable values + for most limits, they may not be appropriate for every + system. Setting a limit too high may open the system up to + abuse, while setting it too low may put a strain on + productivity.</para> + </listitem> + + <listitem> + <para>Users of <application>&xorg;</application> should + probably be granted more resources than other users. + <application>&xorg;</application> by itself takes a lot of + resources, but it also encourages users to run more programs + simultaneously.</para> + </listitem> + + <listitem> + <para>Many limits apply to individual processes, not the user + as a whole. For example, setting + <varname>openfiles</varname> to 50 means that each process + the user runs may open up to 50 files. The total amount + of files a user may open is the value of + <literal>openfiles</literal> multiplied by the value of + <literal>maxproc</literal>. This also applies to memory + consumption.</para> + </listitem> + </itemizedlist> + + <para>For further information on resource limits and login classes + and capabilities in general, refer to &man.cap.mkdb.1;, + &man.getrlimit.2;, and &man.login.conf.5;.</para> + </sect1> + + <sect1 id="users-groups"> + <title>Groups</title> + + <indexterm><primary>groups</primary></indexterm> + <indexterm> + <primary><filename>/etc/groups</filename></primary> + </indexterm> + <indexterm> + <primary>accounts</primary> + <secondary>groups</secondary> + </indexterm> + <para>A group is a list of users. A group is identified by its + group name and <acronym>GID</acronym>. In &os;, the + kernel uses the <acronym>UID</acronym> of a process, and the + list of groups it belongs to, to determine what the process is + allowed to do. Most of the time, the <acronym>GID</acronym> of + a user or process usually means the first group in the + list.</para> + + <para>The group name to <acronym>GID</acronym> mapping is listed + in <filename>/etc/group</filename>. This is a plain text file + with four colon-delimited fields. The first field is the group + name, the second is the encrypted password, the third the + <acronym>GID</acronym>, and the fourth the comma-delimited list + of members. For a more complete description of the syntax, + refer to &man.group.5;.</para> + + <para>The superuser can modify <filename>/etc/group</filename> + using a text editor. Alternatively, &man.pw.8; can be used to + add and edit groups. For example, to add a group called + <groupname>teamtwo</groupname> and then confirm that it + exists:</para> + + <example> + <title>Adding a Group Using &man.pw.8;</title> + + <screen>&prompt.root; <userinput>pw groupadd teamtwo</userinput> +&prompt.root; <userinput>pw groupshow teamtwo</userinput> +teamtwo:*:1100:</screen> + </example> + + <para>In this example, <literal>1100</literal> is the + <acronym>GID</acronym> of <groupname>teamtwo</groupname>. Right + now, <groupname>teamtwo</groupname> has no members. This + command will add <username>jru</username> as a member of + <groupname>teamtwo</groupname>.</para> + + <example> + <title>Adding User Accounts to a New Group Using + &man.pw.8;</title> + + <screen>&prompt.root; <userinput>pw groupmod teamtwo -M jru</userinput> +&prompt.root; <userinput>pw groupshow teamtwo</userinput> +teamtwo:*:1100:jru</screen> + </example> + + <para>The argument to <option>-M</option> is a comma-delimited + list of users to be added to a new (empty) group or to replace + the members of an existing group. To the user, this group + membership is different from (and in addition to) the user's + primary group listed in the password file. This means that + the user will not show up as a member when using + <option>groupshow</option> with &man.pw.8;, but will show up + when the information is queried via &man.id.1; or a similar + tool. When &man.pw.8; is used to add a user to a group, it only + manipulates <filename>/etc/group</filename> and does not attempt + to read additional data from + <filename>/etc/passwd</filename>.</para> + + <example> + <title>Adding a New Member to a Group Using &man.pw.8;</title> + + <screen>&prompt.root; <userinput>pw groupmod teamtwo -m db</userinput> +&prompt.root; <userinput>pw groupshow teamtwo</userinput> +teamtwo:*:1100:jru,db</screen> + </example> + + <para>In this example, the argument to <option>-m</option> is a + comma-delimited list of users who are to be added to the group. + Unlike the previous example, these users are appended to the + group list and do not replace the list of existing users in the + group.</para> + + <example> + <title>Using &man.id.1; to Determine Group Membership</title> + + <screen>&prompt.user; <userinput>id jru</userinput> +uid=1001(jru) gid=1001(jru) groups=1001(jru), 1100(teamtwo)</screen> + </example> + + <para>In this example, <username>jru</username> is a member of the + groups <groupname>jru</groupname> and + <groupname>teamtwo</groupname>.</para> + + <para>For more information about this command and the format of + <filename>/etc/group</filename>, refer to &man.pw.8; and + &man.group.5;.</para> + </sect1> + + <sect1 id="users-becomesuper"> + <title>Becoming Superuser</title> + + <para>There are several ways to do things as the superuser. The + worst way is to log in as <username>root</username> directly. + Usually very little activity requires <username>root</username> + so logging off and logging in as <username>root</username>, + performing tasks, then logging off and on again as a normal user + is a waste of time.</para> + + <para>A better way is to use &man.su.1; without providing a login + but using <literal>-</literal> to inherit the root environment. + Not providing a login will imply super user. For this to work + the login that must be in the <groupname>wheel</groupname> group. + An example of a typical software installation would involve the + administrator unpacking the software as a normal user and then + elevating their privileges for the build and installation of + the software.</para> + + <example> + <title>Install a Program As The Superuser</title> + + <screen>&prompt.user; <userinput>configure</userinput> +&prompt.user; <userinput>make</userinput> +&prompt.user; <userinput>su -</userinput> +Password: +&prompt.root; <userinput>make install</userinput> +&prompt.root; <userinput>exit</userinput> +&prompt.user;</screen> + </example> + + <para>Note in this example the transition to + <username>root</username> is less painful than logging off + and back on twice.</para> + + <para>Using &man.su.1; works well for single systems or small + networks with just one system administrator. For more complex + environments (or even for these simple environments) + <command>sudo</command> should be used. It is provided as a port, + <filename role="package">security/sudo</filename>. It allows for + things like activity logging, granting users the ability to only + run certain commands as the superuser, and several other + options.</para> + </sect1> +</chapter> diff --git a/en_US.ISO8859-1/books/handbook/vinum/Makefile b/en_US.ISO8859-1/books/handbook/vinum/Makefile new file mode 100644 index 0000000000..b970524581 --- /dev/null +++ b/en_US.ISO8859-1/books/handbook/vinum/Makefile @@ -0,0 +1,15 @@ +# +# Build the Handbook with just the content from this chapter. +# +# $FreeBSD$ +# + +CHAPTERS= vinum/chapter.xml + +VPATH= .. + +MASTERDOC= ${.CURDIR}/../${DOC}.${DOCBOOKSUFFIX} + +DOC_PREFIX?= ${.CURDIR}/../../../.. + +.include "../Makefile" diff --git a/en_US.ISO8859-1/books/handbook/vinum/chapter.xml b/en_US.ISO8859-1/books/handbook/vinum/chapter.xml new file mode 100644 index 0000000000..0b0dc34114 --- /dev/null +++ b/en_US.ISO8859-1/books/handbook/vinum/chapter.xml @@ -0,0 +1,1251 @@ +<?xml version="1.0" encoding="iso-8859-1"?> +<!-- + The Vinum Volume Manager + By Greg Lehey (grog at lemis dot com) + + Added to the Handbook by Hiten Pandya <hmp@FreeBSD.org> + and Tom Rhodes <trhodes@FreeBSD.org> + + For the FreeBSD Documentation Project + $FreeBSD$ +--> + +<chapter id="vinum-vinum"> + <chapterinfo> + <authorgroup> + <author> + <firstname>Greg</firstname> + <surname>Lehey</surname> + <contrib>Originally written by </contrib> + </author> + </authorgroup> + </chapterinfo> + + <title>The <devicename>vinum</devicename> Volume Manager</title> + + <sect1 id="vinum-synopsis"> + <title>Synopsis</title> + + <para>No matter the type of disks, there are always potential + problems. The disks can be too small, too slow, or too + unreliable to meet the system's requirements. While disks are + getting bigger, so are data storage requirements. Often a file + system is needed that is bigger than a disk's capacity. Various + solutions to these problems have been proposed and + implemented.</para> + + <para>One method is through the use of multiple, and sometimes + redundant, disks. In addition to supporting various cards and + controllers for hardware Redundant Array of Independent + Disks <acronym>RAID</acronym> systems, the base &os; system + includes the <devicename>vinum</devicename> volume manager, a + block device driver that implements virtual disk drives and + addresses these three problems. <devicename>vinum</devicename> + provides more flexibility, performance, and reliability than + traditional disk storage and implements + <acronym>RAID</acronym>-0, <acronym>RAID</acronym>-1, and + <acronym>RAID</acronym>-5 models, both individually and in + combination.</para> + + <para>This chapter provides an overview of potential problems with + traditional disk storage, and an introduction to the + <devicename>vinum</devicename> volume manager.</para> + + <note> + <para>Starting with &os; 5, <devicename>vinum</devicename> + has been rewritten in order to fit into the <link + linkend="GEOM">GEOM architecture</link>, while retaining the + original ideas, terminology, and on-disk metadata. This + rewrite is called <emphasis>gvinum</emphasis> (for <emphasis> + GEOM vinum</emphasis>). While this chapter uses the term + <devicename>vinum</devicename>, any command invocations should + be performed with <command>gvinum</command>. The name of the + kernel module has changed from the original + <filename>vinum.ko</filename> to + <filename>geom_vinum.ko</filename>, and all device nodes + reside under <filename + class="directory">/dev/gvinum</filename> instead of + <filename class="directory">/dev/vinum</filename>. As of + &os; 6, the original <devicename>vinum</devicename> + implementation is no longer available in the code base.</para> + </note> + </sect1> + + <sect1 id="vinum-access-bottlenecks"> + <title>Access Bottlenecks</title> + + <para>Modern systems frequently need to access data in a highly + concurrent manner. For example, large FTP or HTTP servers can + maintain thousands of concurrent sessions and have multiple + 100 Mbit/s connections to the outside world, well beyond + the sustained transfer rate of most disks.</para> + + <para>Current disk drives can transfer data sequentially at up to + 70 MB/s, but this value is of little importance in an + environment where many independent processes access a drive, and + where they may achieve only a fraction of these values. In such + cases, it is more interesting to view the problem from the + viewpoint of the disk subsystem. The important parameter is the + load that a transfer places on the subsystem, or the time for + which a transfer occupies the drives involved in the + transfer.</para> + + <para>In any disk transfer, the drive must first position the + heads, wait for the first sector to pass under the read head, + and then perform the transfer. These actions can be considered + to be atomic as it does not make any sense to interrupt + them.</para> + + <para><anchor id="vinum-latency"/> Consider a typical transfer of + about 10 kB: the current generation of high-performance + disks can position the heads in an average of 3.5 ms. The + fastest drives spin at 15,000 rpm, so the average + rotational latency (half a revolution) is 2 ms. At + 70 MB/s, the transfer itself takes about 150 μs, + almost nothing compared to the positioning time. In such a + case, the effective transfer rate drops to a little over + 1 MB/s and is clearly highly dependent on the transfer + size.</para> + + <para>The traditional and obvious solution to this bottleneck is + <quote>more spindles</quote>: rather than using one large disk, + use several smaller disks with the same aggregate storage + space. Each disk is capable of positioning and transferring + independently, so the effective throughput increases by a factor + close to the number of disks used.</para> + + <para>The actual throughput improvement is smaller than the + number of disks involved. Although each drive is capable of + transferring in parallel, there is no way to ensure that the + requests are evenly distributed across the drives. Inevitably + the load on one drive will be higher than on another.</para> + + <indexterm> + <primary>disk concatenation</primary> + </indexterm> + <indexterm> + <primary>Vinum</primary> + <secondary>concatenation</secondary> + </indexterm> + + <para>The evenness of the load on the disks is strongly dependent + on the way the data is shared across the drives. In the + following discussion, it is convenient to think of the disk + storage as a large number of data sectors which are addressable + by number, rather like the pages in a book. The most obvious + method is to divide the virtual disk into groups of consecutive + sectors the size of the individual physical disks and store them + in this manner, rather like taking a large book and tearing it + into smaller sections. This method is called + <emphasis>concatenation</emphasis> and has the advantage that + the disks are not required to have any specific size + relationships. It works well when the access to the virtual + disk is spread evenly about its address space. When access is + concentrated on a smaller area, the improvement is less marked. + <xref linkend="vinum-concat"/> illustrates the sequence in + which storage units are allocated in a concatenated + organization.</para> + + <para> + <figure id="vinum-concat"> + <title>Concatenated Organization</title> + + <graphic fileref="vinum/vinum-concat"/> + </figure></para> + + <indexterm> + <primary>disk striping</primary> + </indexterm> + <indexterm> + <primary>Vinum</primary> + <secondary>striping</secondary> + </indexterm> + <indexterm> + <primary><acronym>RAID</acronym></primary> + </indexterm> + + <para>An alternative mapping is to divide the address space into + smaller, equal-sized components and store them sequentially on + different devices. For example, the first 256 sectors may be + stored on the first disk, the next 256 sectors on the next disk + and so on. After filling the last disk, the process repeats + until the disks are full. This mapping is called + <emphasis>striping</emphasis> or + <acronym>RAID-0</acronym>.</para> + + <para><acronym>RAID</acronym> offers various forms of fault + tolerance, though <acronym>RAID-0</acronym> is somewhat + misleading as it provides no redundancy. Striping requires + somewhat more effort to locate the data, and it can cause + additional I/O load where a transfer is spread over multiple + disks, but it can also provide a more constant load across the + disks. <xref linkend="vinum-striped"/> illustrates the + sequence in which storage units are allocated in a striped + organization.</para> + + <para> + <figure id="vinum-striped"> + <title>Striped Organization</title> + + <graphic fileref="vinum/vinum-striped"/> + </figure></para> + </sect1> + + <sect1 id="vinum-data-integrity"> + <title>Data Integrity</title> + + <para>The final problem with disks is that they are unreliable. + Although reliability has increased tremendously over the last + few years, disk drives are still the most likely core component + of a server to fail. When they do, the results can be + catastrophic and replacing a failed disk drive and restoring + data can result in server downtime.</para> + + <indexterm> + <primary>disk mirroring</primary> + </indexterm> + <indexterm><primary>vinum</primary> + <secondary>mirroring</secondary> + </indexterm> + <indexterm><primary><acronym>RAID</acronym>-1</primary> + </indexterm> + + <para>One approach to this problem is + <emphasis>mirroring</emphasis>, or + <acronym>RAID-1</acronym>, which keeps two copies of the + data on different physical hardware. Any write to the volume + writes to both disks; a read can be satisfied from either, so if + one drive fails, the data is still available on the other + drive.</para> + + <para>Mirroring has two problems:</para> + + <itemizedlist> + <listitem> + <para>It requires twice as much disk storage as a + non-redundant solution.</para> + </listitem> + + <listitem> + <para>Writes must be performed to both drives, so they take up + twice the bandwidth of a non-mirrored volume. Reads do not + suffer from a performance penalty and can even be + faster.</para> + </listitem> + </itemizedlist> + + <indexterm><primary><acronym>RAID</acronym>-5</primary></indexterm> + + <para>An alternative solution is <emphasis>parity</emphasis>, + implemented in <acronym>RAID</acronym> levels 2, 3, 4 and 5. + Of these, <acronym>RAID-5</acronym> is the most interesting. As + implemented in <devicename>vinum</devicename>, it is a variant + on a striped organization which dedicates one block of each + stripe to parity one of the other blocks. As implemented by + <devicename>vinum</devicename>, a + <acronym>RAID-5</acronym> plex is similar to a striped plex, + except that it implements <acronym>RAID-5</acronym> by + including a parity block in each stripe. As required by + <acronym>RAID-5</acronym>, the location of this parity block + changes from one stripe to the next. The numbers in the data + blocks indicate the relative block numbers.</para> + + <para> + <figure id="vinum-raid5-org"> + <title><acronym>RAID</acronym>-5 Organization</title> + + <graphic fileref="vinum/vinum-raid5-org"/> + </figure></para> + + <para>Compared to mirroring, <acronym>RAID-5</acronym> has the + advantage of requiring significantly less storage space. Read + access is similar to that of striped organizations, but write + access is significantly slower, approximately 25% of the read + performance. If one drive fails, the array can continue to + operate in degraded mode where a read from one of the remaining + accessible drives continues normally, but a read from the + failed drive is recalculated from the corresponding block from + all the remaining drives.</para> + </sect1> + + <sect1 id="vinum-objects"> + <title><devicename>vinum</devicename> Objects</title> + + <para>In order to address these problems, + <devicename>vinum</devicename> implements a four-level hierarchy + of objects:</para> + + <itemizedlist> + <listitem> + <para>The most visible object is the virtual disk, called a + <emphasis>volume</emphasis>. Volumes have essentially the + same properties as a &unix; disk drive, though there are + some minor differences. For one, they have no size + limitations.</para> + </listitem> + + <listitem> + <para>Volumes are composed of <emphasis>plexes</emphasis>, + each of which represent the total address space of a + volume. This level in the hierarchy provides redundancy. + Think of plexes as individual disks in a mirrored array, + each containing the same data.</para> + </listitem> + + <listitem> + <para>Since <devicename>vinum</devicename> exists within the + &unix; disk storage framework, it would be possible to use + &unix; partitions as the building block for multi-disk + plexes. In fact, this turns out to be too inflexible as + &unix; disks can have only a limited number of partitions. + Instead, <devicename>vinum</devicename> subdivides a single + &unix; partition, the <emphasis>drive</emphasis>, into + contiguous areas called <emphasis>subdisks</emphasis>, which + are used as building blocks for plexes.</para> + </listitem> + + <listitem> + <para>Subdisks reside on <devicename>vinum</devicename> + <emphasis>drives</emphasis>, currently &unix; partitions. + <devicename>vinum</devicename> drives can contain any + number of subdisks. With the exception of a small area at + the beginning of the drive, which is used for storing + configuration and state information, the entire drive is + available for data storage.</para> + </listitem> + </itemizedlist> + + <para>The following sections describe the way these objects + provide the functionality required of + <devicename>vinum</devicename>.</para> + + <sect2> + <title>Volume Size Considerations</title> + + <para>Plexes can include multiple subdisks spread over all + drives in the <devicename>vinum</devicename> configuration. + As a result, the size of an individual drive does not limit + the size of a plex or a volume.</para> + </sect2> + + <sect2> + <title>Redundant Data Storage</title> + + <para><devicename>vinum</devicename> implements mirroring by + attaching multiple plexes to a volume. Each plex is a + representation of the data in a volume. A volume may contain + between one and eight plexes.</para> + + <para>Although a plex represents the complete data of a volume, + it is possible for parts of the representation to be + physically missing, either by design (by not defining a + subdisk for parts of the plex) or by accident (as a result of + the failure of a drive). As long as at least one plex can + provide the data for the complete address range of the volume, + the volume is fully functional.</para> + </sect2> + + <sect2> + <title>Which Plex Organization?</title> + + <para><devicename>vinum</devicename> implements both + concatenation and striping at the plex level:</para> + + <itemizedlist> + <listitem> + <para>A <emphasis>concatenated plex</emphasis> uses the + address space of each subdisk in turn. Concatenated + plexes are the most flexible as they can contain any + number of subdisks, and the subdisks may be of different + length. The plex may be extended by adding additional + subdisks. They require less <acronym>CPU</acronym> + time than striped plexes, though the difference in + <acronym>CPU</acronym> overhead is not measurable. On + the other hand, they are most susceptible to hot spots, + where one disk is very active and others are idle.</para> + </listitem> + + <listitem> + <para>A <emphasis>striped plex</emphasis> stripes the data + across each subdisk. The subdisks must all be the same + size and there must be at least two subdisks in order to + distinguish it from a concatenated plex. The greatest + advantage of striped plexes is that they reduce hot spots. + By choosing an optimum sized stripe, about 256 kB, + the load can be evened out on the component drives. + Extending a plex by adding new subdisks is so complicated + that <devicename>vinum</devicename> does not implement + it.</para> + </listitem> + </itemizedlist> + + <para><xref linkend="vinum-comparison"/> summarizes the + advantages and disadvantages of each plex organization.</para> + + <table id="vinum-comparison" frame="none"> + <title><devicename>vinum</devicename> Plex + Organizations</title> + + <tgroup cols="5"> + <thead> + <row> + <entry>Plex type</entry> + <entry>Minimum subdisks</entry> + <entry>Can add subdisks</entry> + <entry>Must be equal size</entry> + <entry>Application</entry> + </row> + </thead> + + <tbody> + <row> + <entry>concatenated</entry> + <entry>1</entry> + <entry>yes</entry> + <entry>no</entry> + <entry>Large data storage with maximum placement + flexibility and moderate performance</entry> + </row> + + <row> + <entry>striped</entry> + <entry>2</entry> + <entry>no</entry> + <entry>yes</entry> + <entry>High performance in combination with highly + concurrent access</entry> + </row> + </tbody> + </tgroup> + </table> + </sect2> + </sect1> + + <sect1 id="vinum-examples"> + <title>Some Examples</title> + + <para><devicename>vinum</devicename> maintains a + <emphasis>configuration database</emphasis> which describes the + objects known to an individual system. Initially, the user + creates the configuration database from one or more + configuration files using &man.gvinum.8;. + <devicename>vinum</devicename> stores a copy of its + configuration database on each disk + <emphasis>device</emphasis> under its control. This database is + updated on each state change, so that a restart accurately + restores the state of each + <devicename>vinum</devicename> object.</para> + + <sect2> + <title>The Configuration File</title> + + <para>The configuration file describes individual + <devicename>vinum</devicename> objects. The definition of a + simple volume might be:</para> + + <programlisting> drive a device /dev/da3h + volume myvol + plex org concat + sd length 512m drive a</programlisting> + + <para>This file describes four <devicename>vinum</devicename> + objects:</para> + + <itemizedlist> + <listitem> + <para>The <emphasis>drive</emphasis> line describes a disk + partition (<emphasis>drive</emphasis>) and its location + relative to the underlying hardware. It is given the + symbolic name <emphasis>a</emphasis>. This separation of + symbolic names from device names allows disks to be moved + from one location to another without confusion.</para> + </listitem> + + <listitem> + <para>The <emphasis>volume</emphasis> line describes a + volume. The only required attribute is the name, in this + case <emphasis>myvol</emphasis>.</para> + </listitem> + + <listitem> + <para>The <emphasis>plex</emphasis> line defines a plex. + The only required parameter is the organization, in this + case <emphasis>concat</emphasis>. No name is necessary as + the system automatically generates a name from the volume + name by adding the suffix + <emphasis>.p</emphasis><emphasis>x</emphasis>, where + <emphasis>x</emphasis> is the number of the plex in the + volume. Thus this plex will be called + <emphasis>myvol.p0</emphasis>.</para> + </listitem> + + <listitem> + <para>The <emphasis>sd</emphasis> line describes a subdisk. + The minimum specifications are the name of a drive on + which to store it, and the length of the subdisk. No name + is necessary as the system automatically assigns names + derived from the plex name by adding the suffix + <emphasis>.s</emphasis><emphasis>x</emphasis>, where + <emphasis>x</emphasis> is the number of the subdisk in + the plex. Thus <devicename>vinum</devicename> gives this + subdisk the name <emphasis>myvol.p0.s0</emphasis>.</para> + </listitem> + </itemizedlist> + + <para>After processing this file, &man.gvinum.8; produces the + following output:</para> + + <programlisting width="97"> + &prompt.root; gvinum -> <userinput>create config1</userinput> + Configuration summary + Drives: 1 (4 configured) + Volumes: 1 (4 configured) + Plexes: 1 (8 configured) + Subdisks: 1 (16 configured) + + D a State: up Device /dev/da3h Avail: 2061/2573 MB (80%) + + V myvol State: up Plexes: 1 Size: 512 MB + + P myvol.p0 C State: up Subdisks: 1 Size: 512 MB + + S myvol.p0.s0 State: up PO: 0 B Size: 512 MB</programlisting> + + <para>This output shows the brief listing format of + &man.gvinum.8;. It is represented graphically in <xref + linkend="vinum-simple-vol"/>.</para> + + <para> + <figure id="vinum-simple-vol"> + <title>A Simple <devicename>vinum</devicename> + Volume</title> + + <graphic fileref="vinum/vinum-simple-vol"/> + </figure></para> + + <para>This figure, and the ones which follow, represent a + volume, which contains the plexes, which in turn contains the + subdisks. In this example, the volume contains one plex, and + the plex contains one subdisk.</para> + + <para>This particular volume has no specific advantage over a + conventional disk partition. It contains a single plex, so it + is not redundant. The plex contains a single subdisk, so + there is no difference in storage allocation from a + conventional disk partition. The following sections + illustrate various more interesting configuration + methods.</para> + </sect2> + + <sect2> + <title>Increased Resilience: Mirroring</title> + + <para>The resilience of a volume can be increased by mirroring. + When laying out a mirrored volume, it is important to ensure + that the subdisks of each plex are on different drives, so + that a drive failure will not take down both plexes. The + following configuration mirrors a volume:</para> + + <programlisting> drive b device /dev/da4h + volume mirror + plex org concat + sd length 512m drive a + plex org concat + sd length 512m drive b</programlisting> + + <para>In this example, it was not necessary to specify a + definition of drive <emphasis>a</emphasis> again, since + <devicename>vinum</devicename> keeps track of all objects in + its configuration database. After processing this definition, + the configuration looks like:</para> + + <programlisting width="97"> + Drives: 2 (4 configured) + Volumes: 2 (4 configured) + Plexes: 3 (8 configured) + Subdisks: 3 (16 configured) + + D a State: up Device /dev/da3h Avail: 1549/2573 MB (60%) + D b State: up Device /dev/da4h Avail: 2061/2573 MB (80%) + + V myvol State: up Plexes: 1 Size: 512 MB + V mirror State: up Plexes: 2 Size: 512 MB + + P myvol.p0 C State: up Subdisks: 1 Size: 512 MB + P mirror.p0 C State: up Subdisks: 1 Size: 512 MB + P mirror.p1 C State: initializing Subdisks: 1 Size: 512 MB + + S myvol.p0.s0 State: up PO: 0 B Size: 512 MB + S mirror.p0.s0 State: up PO: 0 B Size: 512 MB + S mirror.p1.s0 State: empty PO: 0 B Size: 512 MB</programlisting> + + <para><xref linkend="vinum-mirrored-vol"/> shows the + structure graphically.</para> + + <para> + <figure id="vinum-mirrored-vol"> + <title>A Mirrored <devicename>vinum</devicename> + Volume</title> + + <graphic fileref="vinum/vinum-mirrored-vol"/> + </figure></para> + + <para>In this example, each plex contains the full 512 MB + of address space. As in the previous example, each plex + contains only a single subdisk.</para> + </sect2> + + <sect2> + <title>Optimizing Performance</title> + + <para>The mirrored volume in the previous example is more + resistant to failure than an unmirrored volume, but its + performance is less as each write to the volume requires a + write to both drives, using up a greater proportion of the + total disk bandwidth. Performance considerations demand a + different approach: instead of mirroring, the data is striped + across as many disk drives as possible. The following + configuration shows a volume with a plex striped across four + disk drives:</para> + + <programlisting> drive c device /dev/da5h + drive d device /dev/da6h + volume stripe + plex org striped 512k + sd length 128m drive a + sd length 128m drive b + sd length 128m drive c + sd length 128m drive d</programlisting> + + <para>As before, it is not necessary to define the drives which + are already known to <devicename>vinum</devicename>. After + processing this definition, the configuration looks + like:</para> + + <programlisting width="92"> + Drives: 4 (4 configured) + Volumes: 3 (4 configured) + Plexes: 4 (8 configured) + Subdisks: 7 (16 configured) + + D a State: up Device /dev/da3h Avail: 1421/2573 MB (55%) + D b State: up Device /dev/da4h Avail: 1933/2573 MB (75%) + D c State: up Device /dev/da5h Avail: 2445/2573 MB (95%) + D d State: up Device /dev/da6h Avail: 2445/2573 MB (95%) + + V myvol State: up Plexes: 1 Size: 512 MB + V mirror State: up Plexes: 2 Size: 512 MB + V striped State: up Plexes: 1 Size: 512 MB + + P myvol.p0 C State: up Subdisks: 1 Size: 512 MB + P mirror.p0 C State: up Subdisks: 1 Size: 512 MB + P mirror.p1 C State: initializing Subdisks: 1 Size: 512 MB + P striped.p1 State: up Subdisks: 1 Size: 512 MB + + S myvol.p0.s0 State: up PO: 0 B Size: 512 MB + S mirror.p0.s0 State: up PO: 0 B Size: 512 MB + S mirror.p1.s0 State: empty PO: 0 B Size: 512 MB + S striped.p0.s0 State: up PO: 0 B Size: 128 MB + S striped.p0.s1 State: up PO: 512 kB Size: 128 MB + S striped.p0.s2 State: up PO: 1024 kB Size: 128 MB + S striped.p0.s3 State: up PO: 1536 kB Size: 128 MB</programlisting> + + <para> + <figure id="vinum-striped-vol"> + <title>A Striped <devicename>vinum</devicename> + Volume</title> + + <graphic fileref="vinum/vinum-striped-vol"/> + </figure></para> + + <para>This volume is represented in <xref + linkend="vinum-striped-vol"/>. The darkness of the + stripes indicates the position within the plex address space, + where the lightest stripes come first and the darkest + last.</para> + </sect2> + + <sect2> + <title>Resilience and Performance</title> + + <para><anchor id="vinum-resilience"/>With sufficient hardware, + it is possible to build volumes which show both increased + resilience and increased performance compared to standard + &unix; partitions. A typical configuration file might + be:</para> + + <programlisting> volume raid10 + plex org striped 512k + sd length 102480k drive a + sd length 102480k drive b + sd length 102480k drive c + sd length 102480k drive d + sd length 102480k drive e + plex org striped 512k + sd length 102480k drive c + sd length 102480k drive d + sd length 102480k drive e + sd length 102480k drive a + sd length 102480k drive b</programlisting> + + <para>The subdisks of the second plex are offset by two drives + from those of the first plex. This helps to ensure that + writes do not go to the same subdisks even if a transfer goes + over two drives.</para> + + <para><xref linkend="vinum-raid10-vol"/> represents the + structure of this volume.</para> + + <para> + <figure id="vinum-raid10-vol"> + <title>A Mirrored, Striped <devicename>vinum</devicename> + Volume</title> + + <graphic fileref="vinum/vinum-raid10-vol"/> + </figure></para> + </sect2> + </sect1> + + <sect1 id="vinum-object-naming"> + <title>Object Naming</title> + + <para><devicename>vinum</devicename> assigns default names to + plexes and subdisks, although they may be overridden. + Overriding the default names is not recommended as it does not + bring a significant advantage and it can cause + confusion.</para> + + <para>Names may contain any non-blank character, but it is + recommended to restrict them to letters, digits and the + underscore characters. The names of volumes, plexes, and + subdisks may be up to 64 characters long, and the names of + drives may be up to 32 characters long.</para> + + <para><devicename>vinum</devicename> objects are assigned device + nodes in the hierarchy <filename + class="directory">/dev/gvinum</filename>. The configuration + shown above would cause <devicename>vinum</devicename> to create + the following device nodes:</para> + + <itemizedlist> + <listitem> + <para>Device entries for each volume. These are the main + devices used by <devicename>vinum</devicename>. The + configuration above would include the devices + <filename class="devicefile">/dev/gvinum/myvol</filename>, + <filename class="devicefile">/dev/gvinum/mirror</filename>, + <filename class="devicefile">/dev/gvinum/striped</filename>, + <filename class="devicefile">/dev/gvinum/raid5</filename> + and <filename + class="devicefile">/dev/gvinum/raid10</filename>.</para> + </listitem> + + <listitem> + <para>All volumes get direct entries under + <filename class="directory">/dev/gvinum/</filename>.</para> + </listitem> + + <listitem> + <para>The directories + <filename class="directory">/dev/gvinum/plex</filename>, and + <filename class="directory">/dev/gvinum/sd</filename>, which + contain device nodes for each plex and for each subdisk, + respectively.</para> + </listitem> + </itemizedlist> + + <para>For example, consider the following configuration + file:</para> + + <programlisting> drive drive1 device /dev/sd1h + drive drive2 device /dev/sd2h + drive drive3 device /dev/sd3h + drive drive4 device /dev/sd4h + volume s64 setupstate + plex org striped 64k + sd length 100m drive drive1 + sd length 100m drive drive2 + sd length 100m drive drive3 + sd length 100m drive drive4</programlisting> + + <para>After processing this file, &man.gvinum.8; creates the + following structure in <filename + class="directory">/dev/gvinum</filename>:</para> + + <programlisting> drwxr-xr-x 2 root wheel 512 Apr 13 +16:46 plex + crwxr-xr-- 1 root wheel 91, 2 Apr 13 16:46 s64 + drwxr-xr-x 2 root wheel 512 Apr 13 16:46 sd + + /dev/vinum/plex: + total 0 + crwxr-xr-- 1 root wheel 25, 0x10000002 Apr 13 16:46 s64.p0 + + /dev/vinum/sd: + total 0 + crwxr-xr-- 1 root wheel 91, 0x20000002 Apr 13 16:46 s64.p0.s0 + crwxr-xr-- 1 root wheel 91, 0x20100002 Apr 13 16:46 s64.p0.s1 + crwxr-xr-- 1 root wheel 91, 0x20200002 Apr 13 16:46 s64.p0.s2 + crwxr-xr-- 1 root wheel 91, 0x20300002 Apr 13 16:46 s64.p0.s3</programlisting> + + <para>Although it is recommended that plexes and subdisks should + not be allocated specific names, + <devicename>vinum</devicename> drives must be named. This makes + it possible to move a drive to a different location and still + recognize it automatically. Drive names may be up to 32 + characters long.</para> + + <sect2> + <title>Creating File Systems</title> + + <para>Volumes appear to the system to be identical to disks, + with one exception. Unlike &unix; drives, + <devicename>vinum</devicename> does not partition volumes, + which thus do not contain a partition table. This has + required modification to some disk utilities, notably + &man.newfs.8;, so that it does not try to interpret the last + letter of a <devicename>vinum</devicename> volume name as a + partition identifier. For example, a disk drive may have a + name like <filename class="devicefile">/dev/ad0a</filename> + or <filename class="devicefile">/dev/da2h</filename>. These + names represent the first partition + (<devicename>a</devicename>) on the first (0) IDE disk + (<devicename>ad</devicename>) and the eighth partition + (<devicename>h</devicename>) on the third (2) SCSI disk + (<devicename>da</devicename>) respectively. By contrast, a + <devicename>vinum</devicename> volume might be called + <filename class="devicefile">/dev/gvinum/concat</filename>, + which has no relationship with a partition name.</para> + + <para>In order to create a file system on this volume, use + &man.newfs.8;:</para> + + <screen>&prompt.root; <userinput>newfs /dev/gvinum/concat</userinput></screen> + </sect2> + </sect1> + + <sect1 id="vinum-config"> + <title>Configuring <devicename>vinum</devicename></title> + + <para>The <filename>GENERIC</filename> kernel does not contain + <devicename>vinum</devicename>. It is possible to build a + custom kernel which includes <devicename>vinum</devicename>, but + this is not recommended. The standard way to start + <devicename>vinum</devicename> is as a kernel module. + &man.kldload.8; is not needed because when &man.gvinum.8; + starts, it checks whether the module has been loaded, and if it + is not, it loads it automatically.</para> + + + <sect2> + <title>Startup</title> + + <para><devicename>vinum</devicename> stores configuration + information on the disk slices in essentially the same form as + in the configuration files. When reading from the + configuration database, <devicename>vinum</devicename> + recognizes a number of keywords which are not allowed in the + configuration files. For example, a disk configuration might + contain the following text:</para> + + <programlisting width="119">volume myvol state up +volume bigraid state down +plex name myvol.p0 state up org concat vol myvol +plex name myvol.p1 state up org concat vol myvol +plex name myvol.p2 state init org striped 512b vol myvol +plex name bigraid.p0 state initializing org raid5 512b vol bigraid +sd name myvol.p0.s0 drive a plex myvol.p0 state up len 1048576b driveoffset 265b plexoffset 0b +sd name myvol.p0.s1 drive b plex myvol.p0 state up len 1048576b driveoffset 265b plexoffset 1048576b +sd name myvol.p1.s0 drive c plex myvol.p1 state up len 1048576b driveoffset 265b plexoffset 0b +sd name myvol.p1.s1 drive d plex myvol.p1 state up len 1048576b driveoffset 265b plexoffset 1048576b +sd name myvol.p2.s0 drive a plex myvol.p2 state init len 524288b driveoffset 1048841b plexoffset 0b +sd name myvol.p2.s1 drive b plex myvol.p2 state init len 524288b driveoffset 1048841b plexoffset 524288b +sd name myvol.p2.s2 drive c plex myvol.p2 state init len 524288b driveoffset 1048841b plexoffset 1048576b +sd name myvol.p2.s3 drive d plex myvol.p2 state init len 524288b driveoffset 1048841b plexoffset 1572864b +sd name bigraid.p0.s0 drive a plex bigraid.p0 state initializing len 4194304b driveoff set 1573129b plexoffset 0b +sd name bigraid.p0.s1 drive b plex bigraid.p0 state initializing len 4194304b driveoff set 1573129b plexoffset 4194304b +sd name bigraid.p0.s2 drive c plex bigraid.p0 state initializing len 4194304b driveoff set 1573129b plexoffset 8388608b +sd name bigraid.p0.s3 drive d plex bigraid.p0 state initializing len 4194304b driveoff set 1573129b plexoffset 12582912b +sd name bigraid.p0.s4 drive e plex bigraid.p0 state initializing len 4194304b driveoff set 1573129b plexoffset 16777216b</programlisting> + + <para>The obvious differences here are the presence of + explicit location information and naming, both of which are + allowed but discouraged, and the information on the states. + <devicename>vinum</devicename> does not store information + about drives in the configuration information. It finds the + drives by scanning the configured disk drives for partitions + with a <devicename>vinum</devicename> label. This enables + <devicename>vinum</devicename> to identify drives correctly + even if they have been assigned different &unix; drive + IDs.</para> + + <sect3 id="vinum-rc-startup"> + <title>Automatic Startup</title> + + <para><emphasis>Gvinum</emphasis> always features an + automatic startup once the kernel module is loaded, via + &man.loader.conf.5;. To load the + <emphasis>Gvinum</emphasis> module at boot time, add + <literal>geom_vinum_load="YES"</literal> to + <filename>/boot/loader.conf</filename>.</para> + + <para>When <devicename>vinum</devicename> is started with + <command>gvinum start</command>, + <devicename>vinum</devicename> reads the configuration + database from one of the <devicename>vinum</devicename> + drives. Under normal circumstances, each drive contains + an identical copy of the configuration database, so it + does not matter which drive is read. After a crash, + however, <devicename>vinum</devicename> must determine + which drive was updated most recently and read the + configuration from this drive. It then updates the + configuration, if necessary, from progressively older + drives.</para> + </sect3> + </sect2> + </sect1> + + <sect1 id="vinum-root"> + <title>Using <devicename>vinum</devicename> for the Root + File System</title> + + <para>For a machine that has fully-mirrored file systems using + <devicename>vinum</devicename>, it is desirable to also + mirror the root file system. Setting up such a configuration + is less trivial than mirroring an arbitrary file system + because:</para> + + <itemizedlist> + <listitem> + <para>The root file system must be available very early + during the boot process, so the + <devicename>vinum</devicename> infrastructure must + already be available at this time.</para> + </listitem> + <listitem> + <para>The volume containing the root file system also + contains the system bootstrap and the kernel. These must + be read using the host system's native utilities, such as + the BIOS, which often cannot be taught about the details + of <devicename>vinum</devicename>.</para> + </listitem> + </itemizedlist> + + <para>In the following sections, the term <quote>root + volume</quote> is generally used to describe the + <devicename>vinum</devicename> volume that contains the root + file system.</para> + + <sect2> + <title>Starting up <devicename>vinum</devicename> Early + Enough for the Root File System</title> + + <para><devicename>vinum</devicename> must be available early + in the system boot as &man.loader.8; must be able to load + the vinum kernel module before starting the kernel. This + can be accomplished by putting this line in + <filename>/boot/loader.conf</filename>:</para> + + <programlisting>geom_vinum_load="YES"</programlisting> + + </sect2> + + <sect2> + <title>Making a <devicename>vinum</devicename>-based Root + Volume Accessible to the Bootstrap</title> + + <para>The current &os; bootstrap is only 7.5 KB of code and + does not understand the internal + <devicename>vinum</devicename> structures. This means that it + cannot parse the <devicename>vinum</devicename> configuration + data or figure out the elements of a boot volume. Thus, some + workarounds are necessary to provide the bootstrap code with + the illusion of a standard <literal>a</literal> partition + that contains the root file system.</para> + + <para>For this to be possible, the following requirements must + be met for the root volume:</para> + + <itemizedlist> + <listitem> + <para>The root volume must not be a stripe or + <acronym>RAID</acronym>-5.</para> + </listitem> + + <listitem> + <para>The root volume must not contain more than one + concatenated subdisk per plex.</para> + </listitem> + </itemizedlist> + + <para>Note that it is desirable and possible to use multiple + plexes, each containing one replica of the root file system. + The bootstrap process will only use one replica for finding + the bootstrap and all boot files, until the kernel mounts the + root file system. Each single subdisk within these plexes + needs its own <literal>a</literal> partition illusion, for + the respective device to be bootable. It is not strictly + needed that each of these faked <literal>a</literal> + partitions is located at the same offset within its device, + compared with other devices containing plexes of the root + volume. However, it is probably a good idea to create the + <devicename>vinum</devicename> volumes that way so the + resulting mirrored devices are symmetric, to avoid + confusion.</para> + + <para>In order to set up these <literal>a</literal> + partitions for each device containing part of the root + volume, the following is required:</para> + + <procedure> + <step> + <para>The location, offset from the beginning of the device, + and size of this device's subdisk that is part of the root + volume needs to be examined, using the command:</para> + + <screen>&prompt.root; <userinput>gvinum l -rv root</userinput></screen> + + <para><devicename>vinum</devicename> offsets and sizes are + measured in bytes. They must be divided by 512 in order + to obtain the block numbers that are to be used by + <command>bsdlabel</command>.</para> + </step> + + <step> + <para>Run this command for each device that participates in + the root volume:</para> + + <screen>&prompt.root; <userinput>bsdlabel -e <replaceable>devname</replaceable></userinput></screen> + + <para><replaceable>devname</replaceable> must be either the + name of the disk, like <devicename>da0</devicename> for + disks without a slice table, or the name of the + slice, like <devicename>ad0s1</devicename>.</para> + + <para>If there is already an <literal>a</literal> + partition on the device from a + pre-<devicename>vinum</devicename> root file system, it + should be renamed to something else so that it remains + accessible (just in case), but will no longer be used by + default to bootstrap the system. A currently mounted root + file system cannot be renamed, so this must be executed + either when being booted from a <quote>Fixit</quote> + media, or in a two-step process where, in a mirror, the + disk that is not been currently booted is manipulated + first.</para> + + <para>The offset of the <devicename>vinum</devicename> + partition on this device (if any) must be added to the + offset of the respective root volume subdisk on this + device. The resulting value will become the + <literal>offset</literal> value for the new + <literal>a</literal> partition. The + <literal>size</literal> value for this partition can be + taken verbatim from the calculation above. The + <literal>fstype</literal> should be + <literal>4.2BSD</literal>. The + <literal>fsize</literal>, <literal>bsize</literal>, + and <literal>cpg</literal> values should be chosen + to match the actual file system, though they are fairly + unimportant within this context.</para> + + <para>That way, a new <literal>a</literal> partition will + be established that overlaps the + <devicename>vinum</devicename> partition on this device. + <command>bsdlabel</command> will only allow for this + overlap if the <devicename>vinum</devicename> partition + has properly been marked using the + <literal>vinum</literal> fstype.</para> + </step> + + <step> + <para>A faked <literal>a</literal> partition now exists + on each device that has one replica of the root volume. + It is highly recommendable to verify the result using a + command like:</para> + + <screen>&prompt.root; <userinput>fsck -n /dev/<replaceable>devname</replaceable>a</userinput></screen> + </step> + </procedure> + + <para>It should be remembered that all files containing control + information must be relative to the root file system in the + <devicename>vinum</devicename> volume which, when setting up + a new <devicename>vinum</devicename> root volume, might not + match the root file system that is currently active. So in + particular, <filename>/etc/fstab</filename> and + <filename>/boot/loader.conf</filename> need to be taken care + of.</para> + + <para>At next reboot, the bootstrap should figure out the + appropriate control information from the new + <devicename>vinum</devicename>-based root file system, and act + accordingly. At the end of the kernel initialization process, + after all devices have been announced, the prominent notice + that shows the success of this setup is a message like:</para> + + <screen>Mounting root from ufs:/dev/gvinum/root</screen> + </sect2> + + <sect2> + <title>Example of a <devicename>vinum</devicename>-based Root + Setup</title> + + <para>After the <devicename>vinum</devicename> root volume has + been set up, the output of <command>gvinum l -rv + root</command> could look like:</para> + + <screen>... +Subdisk root.p0.s0: + Size: 125829120 bytes (120 MB) + State: up + Plex root.p0 at offset 0 (0 B) + Drive disk0 (/dev/da0h) at offset 135680 (132 kB) + +Subdisk root.p1.s0: + Size: 125829120 bytes (120 MB) + State: up + Plex root.p1 at offset 0 (0 B) + Drive disk1 (/dev/da1h) at offset 135680 (132 kB)</screen> + + <para>The values to note are <literal>135680</literal> for the + offset, relative to partition + <filename class="devicefile">/dev/da0h</filename>. This + translates to 265 512-byte disk blocks in + <command>bsdlabel</command>'s terms. Likewise, the size of + this root volume is 245760 512-byte blocks. <filename + class="devicefile">/dev/da1h</filename>, containing the + second replica of this root volume, has a symmetric + setup.</para> + + <para>The bsdlabel for these devices might look like:</para> + + <screen>... +8 partitions: +# size offset fstype [fsize bsize bps/cpg] + a: 245760 281 4.2BSD 2048 16384 0 # (Cyl. 0*- 15*) + c: 71771688 0 unused 0 0 # (Cyl. 0 - 4467*) + h: 71771672 16 vinum # (Cyl. 0*- 4467*)</screen> + + <para>It can be observed that the <literal>size</literal> + parameter for the faked <literal>a</literal> partition + matches the value outlined above, while the + <literal>offset</literal> parameter is the sum of the offset + within the <devicename>vinum</devicename> partition + <literal>h</literal>, and the offset of this partition + within the device or slice. This is a typical setup that is + necessary to avoid the problem described in <xref + linkend="vinum-root-panic"/>. The entire + <literal>a</literal> partition is completely within the + <literal>h</literal> partition containing all the + <devicename>vinum</devicename> data for this device.</para> + + <para>In the above example, the entire device is dedicated to + <devicename>vinum</devicename> and there is no leftover + pre-<devicename>vinum</devicename> root partition.</para> + </sect2> + + <sect2> + <title>Troubleshooting</title> + + <para>The following list contains a few known pitfalls and + solutions.</para> + + <sect3> + <title>System Bootstrap Loads, but System Does Not + Boot</title> + + <para>If for any reason the system does not continue to boot, + the bootstrap can be interrupted by pressing + <keycap>space</keycap> at the 10-seconds warning. The + loader variable <literal>vinum.autostart</literal> can be + examined by typing <command>show</command> and manipulated + using <command>set</command> or + <command>unset</command>.</para> + + <para>If the <devicename>vinum</devicename> kernel module was + not yet in the list of modules to load automatically, type + <command>load geom_vinum</command>.</para> + + <para>When ready, the boot process can be continued by typing + <command>boot -as</command> which + <option>-as</option> requests the kernel to ask for the + root file system to mount (<option>-a</option>) and make the + boot process stop in single-user mode (<option>-s</option>), + where the root file system is mounted read-only. That way, + even if only one plex of a multi-plex volume has been + mounted, no data inconsistency between plexes is being + risked.</para> + + <para>At the prompt asking for a root file system to mount, + any device that contains a valid root file system can be + entered. If <filename>/etc/fstab</filename> is set up + correctly, the default should be something like + <literal>ufs:/dev/gvinum/root</literal>. A typical + alternate choice would be something like + <literal>ufs:da0d</literal> which could be a + hypothetical partition containing the + pre-<devicename>vinum</devicename> root file system. Care + should be taken if one of the alias + <literal>a</literal> partitions is entered here, that it + actually references the subdisks of the + <devicename>vinum</devicename> root device, because in a + mirrored setup, this would only mount one piece of a + mirrored root device. If this file system is to be mounted + read-write later on, it is necessary to remove the other + plex(es) of the <devicename>vinum</devicename> root volume + since these plexes would otherwise carry inconsistent + data.</para> + </sect3> + + <sect3> + <title>Only Primary Bootstrap Loads</title> + + <para>If <filename>/boot/loader</filename> fails to load, but + the primary bootstrap still loads (visible by a single dash + in the left column of the screen right after the boot + process starts), an attempt can be made to interrupt the + primary bootstrap by pressing + <keycap>space</keycap>. This will make the bootstrap stop + in <link linkend="boot-boot1">stage two</link>. An attempt + can be made here to boot off an alternate partition, like + the partition containing the previous root file system that + has been moved away from <literal>a</literal>.</para> + </sect3> + + <sect3 id="vinum-root-panic"> + <title>Nothing Boots, the Bootstrap + Panics</title> + + <para>This situation will happen if the bootstrap had been + destroyed by the <devicename>vinum</devicename> + installation. Unfortunately, <devicename>vinum</devicename> + accidentally leaves only 4 KB at the beginning of its + partition free before starting to write its + <devicename>vinum</devicename> header information. However, + the stage one and two bootstraps plus the bsdlabel require 8 + KB. So if a <devicename>vinum</devicename> partition was + started at offset 0 within a slice or disk that was meant to + be bootable, the <devicename>vinum</devicename> setup will + trash the bootstrap.</para> + + <para>Similarly, if the above situation has been recovered, + by booting from a <quote>Fixit</quote> media, and the + bootstrap has been re-installed using + <command>bsdlabel -B</command> as described in <xref + linkend="boot-boot1"/>, the bootstrap will trash the + <devicename>vinum</devicename> header, and + <devicename>vinum</devicename> will no longer find its + disk(s). Though no actual <devicename>vinum</devicename> + configuration data or data in <devicename>vinum</devicename> + volumes will be trashed, and it would be possible to recover + all the data by entering exactly the same + <devicename>vinum</devicename> configuration data again, the + situation is hard to fix. It is necessary to move the + entire <devicename>vinum</devicename> partition by at least + 4 KB, in order to have the <devicename>vinum</devicename> + header and the system bootstrap no longer collide.</para> + </sect3> + </sect2> + </sect1> +</chapter> diff --git a/en_US.ISO8859-1/books/porters-handbook/uses.xml b/en_US.ISO8859-1/books/porters-handbook/uses.xml index 6592275cfc..08c77bd1b4 100644 --- a/en_US.ISO8859-1/books/porters-handbook/uses.xml +++ b/en_US.ISO8859-1/books/porters-handbook/uses.xml @@ -257,7 +257,7 @@ and <application>PHP</application> are supported by default. To support another interpreter, set <makevar>SHEBANG_LANG</makevar> (for example - <literal><makevar>SHEBANG_LANG</makevar>=lua</literal>), then + <literal>SHEBANG_LANG=lua</literal>), then <makevar>lua_OLD_CMD</makevar> and <makevar>lua_CMD</makevar>.</entry> </row> |